SimHeart 3.0

Some months ago, I wrote a series of posts about the behavior of my NetLogo heart simulation (namely, this one and this other one). SimHeart has been on the backburner since then, partly because I was making some effort (some) to pay attention to my classes, but mostly because I didn’t have any new ideas to implement. Then, a couple of weeks ago, I was messing around in NetLogo, trying to figure out how to get the cells of the grid to obey a switching-on rule similar to the kind of rules you find in neural networks. That, as it turned out, was a huge bust, but I re-used some of the code to build SimHeart 3.0.

This is a pretty radical revision, but, behaviorally, it’s pretty much the same as the old simulator. Still, there are some changes:

  • The cells, not the agents, do most of the work. Whether they fire or not is determined by a stochastic (random) sigmoid function. If a lot of a particular cell’s neighbors have high potential (the primary variable; actually, three varaibles, one for each system, but I’ll get to that later) and the cell’s potential is low enough, then the cell has a very high probability of switching its potential to 1. If not, the potential steadily drops.
  • The AV node is now fully simulated. I mentioned in my previous posts that I wanted to do this, and since the atria and the ventricles are simulated as two different kinds of potential, all I had to do to simulate the AV node was to introduce a third variant of the potential variable. Now, a heartbeat starts at the SA node (meaning a particular cell’s potential is set to 1), the wave travels until it reaches the entry cell for the AV node, triggers another wave (one that’s morphologically different, which I’ll talk about in the next bullet point) in the AV node, which travels to the exit cell, triggering the ventricular beat. This solution has the nice feature of taking care of the AV node’s natural delay for me, as well as realistically limiting the heart rate that the AV node can transmit from the atria to the ventricles. This is, by far, the most important addition.
  • The model now runs faster. Not much faster, but every bit counts, and given how much simpler the code is now, the model is now much more compact and elegant.
  • The model is more realistic. The stochastic potential-based cells are a lot more like how a real heart works than was the old model.
  • The model now takes into account the different sizes of the heart’s components. Because of the way the model works, the longer a cell’s potential takes to decay, the smaller of the particular component being simulated. Thus, the potential in the AV node takes a very long time to decay, making nodal arrhythmias essentially impossible (and making the AV node behave as though it’s very small); the potential in the atria takes a moderate amount of time to decay, making atrial arrhythmias much less common (and making the atria behave as though they’re larger than the AV node, but smaller than the ventricles. I think you see the pattern here.), and the potential in the ventricles decays quickly, making them fairly arrhythmia-prone.
  • The arrhythmias have changed. This isn’t necessarily a good thing, but it’s not crippling, either. The model now produces ventricular tachycardia much more readily than it did before, but the incidence of ventricular fibrillation has been reduced proportionately, and can be hard to differentiate between tachycardia. Unless the parameters are adjusted, atrial arrhythmais don’t occur at all. Still, the model can now incorporate junctional tachycardia (where a spiralling, self-sustaining wave in the AV node stimulates the ventricles to beat too quickly) can now be simulated easily.

And, not mentioned on the list above, the model is now prettier, too, since I was apparently experiencing some aesthetic inspiration when I was writing it. So, in SimHeart tradition (can I call it a tradition after three posts?), I present: the screenshots (note: ignore the weird screwed-up areas. They’re just explanatory text that apparently didn’t transfer into the screenshot. Don’t worry, you’re not missing anything, it’s all explained in the text below):

Periodically (with the period determined by the “s-rate” slider next to the view), the cell labeled “SA” sets its potential to 1, generating the atrial pulse (the red wave). If, for some reason (for example, if the atria are in fibrillation and there’s already a wave passing through the SA node), no wave will be generated.

When the pulse passing through the atria hits the cell labeled “AV1,” if there’s not a wave passing through it at the moment, it triggers a pulse in the AV node (the green wave).

If all goes well, the AV pulse triggers the cell labeled “AV2” which activates the ventricular pulse (the blue wave).

Of course, all does not always go well:

In this case, something has gone wrong with the electrical wave as it moves through the ventricles, causing a deadly spiral wave to form. This is simulated ventricular tachycardia, which will (probably) eventually decay into ventricular fibrillation. As you can see on the ECG, the atrial pulses are still trying to get through, but the AV node can’t activate the ventricles. Although it’s not pictured here, a quick press of the “Defibrillate” button took care of the arrhythmia.

Since the model’s now so much simpler, it’s easier to simulate diseases and treatments. Note the row of blue buttons on the right side of the images. There is, of course, the defibrillate button, which is remarkably effective at terminating arrhythmias. Below that are the “Increase Adrenalin” and “Increase Antiarrhythmics” buttons, the first of which makes the heart depolarize faster, and the second of which makes it depolarize more slowly. The first, as you might expect, makes the heart more arrhythmia-prone, and the second, obviously, makes it less arrhythmia-prone.

The set of buttons below that simulate various cardiac illnesses. “AV Block” makes the AV node’s cells depolarize very slowly, meaning that, when the sinus rate is set to a very high value, not all of the beats are able to get through. This, if I’m not mistaken, represents 2nd-degree AV block, type 1. The button below that, “Sinus Tachycardia”, sets the sinus rate to a very high value, simulating either a disease process or the effect of very strenuous exercise or other stress on the heart. “Long QT Syndrome” is a sort of bastardized version of the real disease, but has the same effect, making the ventricles dangerously more prone to arrhythmia.

All in all, I’m far happier with the new version than I was with either of the old versions. There are still some improvements to be made, however, and I’ll post updates as needed. Soon, I hope to have the model up on the NetLogo website, so that everybody can fiddle around with it.

SimHeart Update

The folks at the NetLogo website have been gracious enough to include SimHeart in their “community models” page, and the result is that there is now a place where you can run the program in your web browser (assuming you have a recent enough version of Java installed). Now, you don’t have to download or install anything in order to run it.

You can find the SimHeart applet here.

Once again, many, many thanks to the creators of NetLogo.

SimHeart — Now Available for Download

All right, as promised, I’ve finally figured out a way that people can download SimHeart to play with it themselves. Many thanks to the folks at NetLogo for automating so much of the process, and thanks to MediaFire.com for the free file hosting.

The file is kind of large because, in order for it to work, I had to put a bunch of Java modules into the folder with it, but it shouldn’t take too long to download, even over a slow-ish Internet connection. When you’ve downloaded it, you’ll need to extract the file to your desktop. I recommend an unzipping program like WinZip or WinAce. The program should (major, major emphasis on should) work on Macs and PCs, but I make no guarantees.

To run the simulation, go into the folder into which you’ve extracted SimHeart, and double click on the HTML file there. It should open up in a new window, and you should see the simulation screen. If you don’t, either you don’t have an up-to-date version of Java, or something went wrong in the download process, or I made a mistake zipping the files. If you checked the previous two things, please leave a comment and describe the problem, and I’ll try to help, although I make no claims to be very good at this kind of thing.

Also, I must provide the obligatory legal disclaimer: I take no responsibility if this file somehow damages your system. To my knowledge, there is absolutely nothing in the file that should do so, but you never know, something might have gotten corrupted or damaged along the way. Also, this software is for entertainment purposes only, and should not be taken as any form of medical advice. I’m not sure why anybody would, but you never know.

Download SimHeart 2.0 here.

If you already have the latest version of NetLogo installed on your computer, you can download the muchhere. If you’re interested in this kind of thing, you should go ahead and download NetLogo (you can do that here). Not only will it allow you to download a much smaller file, but NetLogo comes with a whole cornucopia of fascinating little simulations, and there are more you can download from the Internet. smaller .nlogo file

Okay, apparently, that site decided to get rid of the file, so if you want to have a look at SimHeart, you can find it here, on the NetLogo community models page.

If you have trouble with either of these files, please let me know by commenting on this post. If you don’t want to do that for some reason, send an e-mail to asymptote [døt] inverse [át] gmail [døt] com (Sorry about all the weird characters in there, but that account gets enough spam as it is, without ever having broadcast the address on the Internet, so I figured I’d better obfuscate as much as possible).

I’ll try to update the files as I revise SimHeart, but I seem to be at a point where there’s not much more I can do with it, at least not without rewriting most of the code. I’ll be sure to post updates as they come.

SimHeart 2.0

It seems that every time I sit down to work on my heart-simulation project, I get a lot more done than I was expecting. In my last post on the subject, I talked about how I wanted to integrate a more realistic model of the atrioventricular (AV) node, the little bundle of nerve fibers that carries the contraction impulse from the atria at the top of the heart to the ventricles on the bottom. Apparently, I’d entirely misjudged the difficulty of this effort, since, once the solution occurred to me, I was able to implement it in about five minutes.

Here’s what I did. As I said before, each cell in the simulation has two variables assigned to it: ARefrac, which determines whether or not an atrial impulse can pass through the cell; and VRefrac, which determines whether a ventricular impulse can pass through. I solved the AV-realism problem by simply introducing a global variable called AVRefrac that determines whether or not the AV node can accept an impulse. Basically, every time a simulated electrical “spark” strikes the simulated node, as long as AVRefrac is equal to or less than zero, it sets AVRefrac’s value to a user-specified constant I call AV-delay. So, basically, now the ventricles can only respond as fast as the AV node will allow, just like a real heart! When I saw how beautifully my little fix had worked, I was thrilled!

So, my simulated heart is now more realistic than ever. For example, I did a few runs with the refract-length value (the value that determines how quickly cells recover their ability to fire after each firing) set very short so that arrhythmias would occur frequently, so that I could study their effects. Before long, my simulated heart went into atrial flutter/fibrillation (a condition where the small pumping chambers at the top of the heart expand and contract quickly and chaotically, often leading to a dangerously fast ventricular rate. I was amazed to see something very similar to the many atrial-fibrillation EKG’s I’ve looked at:

(Note: in the simulated EKG, I’ve separated the atrial and ventricular signals, since whenever the ventricular rate got very fast, it obscured all the atrial activity, and I wanted to be able to study the atrial activity as well)

Given my tendency towards oversimplified simulations that produce peculiar behavior, the resemblance this bears to real supraventricular tachycardia (fast heart rate caused by the atria, which is often seen in atrial flutter or fibrillation) was frankly, surprising. After about half a second of atrial flutter, the atria begin to fibrillate, producing that classic irregular ventricular response.

Note the extremely high ventricular rate that shows up towards the end of the ECG. That’s a rather unrealistic product of my simulation, since whenever one of the waves of excitation collided with the back of a previous wave, it had a tendency to collapse into a tachycardic or fibrillatory spiral.

There are some forms of supraventricular tachycardia that terminate on their own. They’re called “paroxysmal” supraventricular tachycardia, and my simple little simulation actually managed to produce a run of it!

Some forms of atrial fibrillation occur in the presence of heat block (which, in its most common form, is basically a very slow AV node that doesn’t conduct every impulse that passes to it). In those cases, the fibrillation is frequently asymptomatic or minimally symptomatic, since the heart doesn’t end up racing. When I set the AV-delay parameter higher than usual, I observed this very same phenomenon.

Eventually, the aforementioned wave-collision problem had become annoying enough that I decided to re-write part of the simulation so that there was a small probability that an electrical spark could actually cross a cell that had not entirely recovered. That solved a lot of my problems.

In the re-written simulation, atrial fibrillation still produces that classic irregular ventricular heartbeat, and this time, since the waves are more collision-tolerant, the behavior doesn’t immediately degenerate into ventricular fibrillation, which gives me a chance to actually study it properly.

More updates as they’re warranted. And for those reader(s?) who are wondering what the hell has been wrong with me lately, don’t worry, I’ll be turning the blog over to my old cynical, sarcastic self very shortly.

UPDATE:

I was sitting around without much to do, so I opened up SimHeart and let it run in the background. When I checked in on it again a few minutes later, I’d discovered some very interesting behavior:

Apparently, some of the standard sort of atrial fibrillation had started, then, spontaneously self-organized into a coordinated wave spiraling cyclically through the atria. You can see the wave in the screenshot.

This really grabbed my attention, so I watched it for a while, and discovered that, strangely enough, the wave was quite stable.

Not even the normal sinus beats, which occasionally inserted themselves in the path of the wave, were very good at disrupting it. Not long after this screenshot, it degenerated rather suddenly into normal atrial fibrillation.

Then, while having a look at the pictures a few minutes later, I realized something: my simulation had produced true atrial flutter. What I saw before and called atrial flutter was really just organized fibrillation. This, though, exhibits all the classic features of atrial flutter: rapid atrial waves with a sawtooth shape. In this case, since I had the ventricular response set to be fairly quick, it turned into quite realistic atrial tachycardia.

I tried to save the state of the simulation so that I could study it later, but as there are some features of NetLogo with which I’m not entirely familiar, I wasn’t able to do it. So, for now, I guess I’ll just keep running HeartSim in the background until I see that rhythm again.

The Simulated Heart

For the past few months, I’ve been playing around in a program called NetLogo that allows you to simulate agent-based emergent systems with pretty much no effort whatsoever. Being something of a cardiology nerd, I had the idea a while ago to build a vastly simplified model of the electrical conduction in the heart. With the Belousov-Zhabotinski reaction in mind — which appears in James Gleick’s excellent book Chaos, which also has a chapter on the electrical waves of the heart, which is probably what sparked my inspiration in the first place — I set out to build a simple electrical-wave model. What I got was competent enough. At the beginning of the simulation, a single “spark” in the center of the simulation grid would produce a radiating wave. Sometimes, a defect on the front of that wave would cause the wave to dimple, and then to curl in on itself, producing a self-sustaining oscillation.

Some time later, when I began to get interested in cardiology — especially cardiac arrhythmias — I began to realize that my simple little model produced some behavior that was actually strangely comparable to that of a real heart. So, I modified it to be even more heart-like. I programmed the simulator to generate an initial spark at the center of the grid every fifty time steps or so. As I watched the waves propagate across the screen, I was, frankly, mesmerized. For a while, the waves would march along. Then, one of them would go wobbly, curl in on itself, and start oscillating rapidly. It bore a great deal of similarity to some of the real computer simulations of electrical activity in the heart that I’d seen, specifically to those that generated ventricular tachycardia.

With this as an impetus, I spent many hours revising and playing with my system. I recently downloaded the newest version of NetLogo, and decided that it was time to re-write the heart simulator, which had been mangled and cluttered beyond recognition by the process of incremental revision — something that happens to most of my programs.

This newest version — Version 3, by my count — is my most complete yet. A simulated beat travels through the simulated atrium (in the simulation, the atrial activity is represented by yellow waves), then hits the simulated AV node — the part of the heart’s conduction system that connects the atria (the upper chambers) and the ventricles (the lower chambers) — hangs around for a moment, then starts to propagate as a new wave (this one red) through the simulated ventricles. I’ve observed quite a lot of fascinating and remarkably heart-like behavior in my simple model. I’ll run through some of it here.

This is the main screen. All those buttons and sliders set up the simulated heart’s various parameters. If you can see it in this image, the “refract-length” slider controls how quickly the cells become able to fire again after each firing. The quicker that interval, the more easily the heart will go into fibrillation. That’s why I built in the handy little “defibrillate” button you can see to the right of the display.

As I did a run of the simulation to produce an image for this post, I was lucky enough for the simulation to do something interesting almost immediately. Note the oddly distorted third beat. That’s actually the result of an extra breakaway wave in the simulated ventricles. In real life, we call things like that “palpitations” or “premature ventricular contractions.” When the model’s heart rate is faster, you can actually observe the compensatory pause that comes after most premature ventricular contractions.

A final note on this image: in order to make the pretty EKG-like display, I had to cheat a little. In reality, the small waves represent just as much activity as the large ones (since the two grids are exactly the same size) but since the atria are a lot smaller than the ventricles in a real heart, I thought it would be a good idea to de-emphasize their activity a bit. This also has the benefit of making my fake EKG look a lot more like a real one. I’m currently working on a way to make the conduction in the simulated atria more realistic.

Here, the simulated heart degenerates into the deadly arrhythmia known as ventricular fibrillation. In this often-fatal arrhythmia — which is the primary cause of sudden cardiac arrest syndromes — the ventricles, which represent the majority of the heart’s mechanical pumping power, simply begin to wiggle and wobble randomly, rather than beating in an organized fashion. The result is that no blood gets to the body and the brain, and death results in about ten minutes.

I observed quite a lot of fibrillation of one kind or another in my simulated heart. Since I intentionally set the refractory time short — that is, the cells recovered their firing ability quickly — the waves had a strong tendency to curl in on themselves and break up into spirals. These spiral waves quickly degenerated into clusters of randomly-oscillating cells. About two-thirds of the way through the run, you can see that the fibrillation suddenly stops. That was the result of me pressing the “defibrillate” button, which sends ninety percent of the cells into the refractory phase, unable to fire until they recover. Towards the end, you can see that the “normal sinus rhythm” returns.

I’m actually quite pleased with this little simulation. It wasn’t terribly hard to build — then again, nothing in NetLogo is — and it produces interesting results. Here are my current goals for it:

  • Change some of the parameters so that they better reflect the physical disparities between the atria and the ventricles.
  • Improve my model of the AV node so that it discharges more realistically. Currently, it simply causes the electrical particles to pause for a moment, after which they are released. This means that, unlike the real AV node, my simulated one has a “memory,” and rather than discharging all at once like the real version, it simply discharges in the same order as the pulses that strike it.
  • Incorporate some kind of system to simulate damage to the heart.
  • Refine the electrical model so that the simulation is capable of producing ventricular tachycardia — a dangerous but more organized cousin of ventricular fibrillation in which a single self-sustaining oscillating spiral causes the ventricles to contract too fast to pump effectively. At the moment, the simulated ventricular tachycardia tends to degenerate into ventricular fibrillation almost immediately, making it difficult to study.
  • Make the translation between the simulated heart and the simulated EKG more realistic, so that it produce something more like a real EKG.
  • Make the model more analog. I’m hoping that this will solve a lot of my problems, but it’s probably going to be one of the hardest features to implement, with the possible exception of the better AV node simulation.

I’ll post updates as they come, and I soon hope to have a Java version of the simulator uploaded so that other people can play with it.