The human body, read from a physiologist's source
This essay is not medical advice. It describes rules taught in every introduction to the subject and arithmetic with published formulas, and it reads a program that states them. Blood compatibility in practice is decided by laboratory testing, a body mass index is a measure for populations that its own namer judged inappropriate for individual evaluation, and the energy and heart-rate formulas are estimates that may deviate significantly from a person's actual value. Nothing here is a dose, a diagnosis or a treatment, and nothing in it is a recommendation for anyone's body. Ask a clinician.
In June 1667 Jean-Baptiste Denys, the physician of Louis XIV, gave a boy of fifteen the blood of a sheep, and the boy survived. Later patients of the same treatment died, and the practice was banned in 1668. The first successful transfusion of human blood to treat bleeding after childbirth came in 1818, when James Blundell at Guy's Hospital in London gave a woman the blood of her husband. For a century and a half between, whether a transfusion worked was largely luck, and what ended the luck was a discovery about a pair of molecules on the surface of red cells, and then a long habit of testing before giving.
The body library for DKE, the Deterministic Knowledge Engine, writes down some of what the introductions teach in DKE Python, and this essay teaches the subject by reading it. You record two kinds of fact. A transfusion is recorded as a donor's blood group and a recipient's, and the library's rules conclude, for each of the three antigens A, B and D, whether the donor's red cells carry it and the recipient's do not, and from that whether the red cells would react and whether they put the recipient at risk of sensitisation. A person is recorded by mass and height, and the rules conclude the bands of the World Health Organization from the body mass index. The second half of the library calculates: the index, a resting energy, a body surface and the maximum heart rate by two formulas. Every program below runs as shown once the library's source file has been compiled into a store, and every output is copied from a run.
1. Blood groups, and what a mismatch is
In 1900 Karl Landsteiner observed that the red cells of one person would clump together when mixed with the serum of another. In 1901 he discovered the ABO groups, and he received the Nobel Prize in Physiology or Medicine for it in 1930. A person of group A has the A antigen on the red cells and anti-B antibodies in the serum, a person of group B the reverse, and a person of group O neither antigen and both antibodies. Landsteiner's students Adriano Sturli and Alfred von Decastello identified the fourth group in 1902, and Ludwik Hirszfeld and Emil von Dungern named it AB in 1910. The third group began as "C", and Hirszfeld and von Dungern called it "0" for null, and in 1927 Landsteiner chose the letter O, after the German ohne, without. The antibodies are usually IgM and develop in early childhood in response to environmental substances such as food, bacteria and viruses. A recipient's antibodies attack the matching antigen on donor red cells, which is the clumping Landsteiner had observed, and a mismatch can cause a potentially fatal reaction after a transfusion.
The second system is the Rh system. Landsteiner and Alexander Wiener discovered it, in 1939 according to the account of the system, and its name comes from the rhesus monkeys whose red cells were used to make the first serum. It has five main antigens, and D is the most immunogenic of those outside the ABO system: "Rh positive" and "Rh negative" refer to the D antigen only. A person who is A+ has the D antigen and a person who is A- lacks it. A D-negative person given D-positive blood may become sensitised to the D antigen, and a female patient so sensitised would then be at risk of hemolytic disease of the newborn in a later pregnancy, a disease that is largely preventable now with injections of anti-D immunoglobulin.
So a group is three antigens, A, B and D, each present or absent. The library takes a group written as A+, AB- or O- and holds it as three numbers, and the rules are three statements of what the donor has and the recipient lacks, and two of what follows from it:
@rule
def lacks_a():
for t in Transfusion:
if t.da > t.ra:
t.lacks_a = True
@rule
def reacts_for_a():
for t in Transfusion:
if t.lacks_a == True:
t.reacts = True
@rule
def sensitises_for_d():
for t in Transfusion:
if t.lacks_d == True:
t.sensitises = TrueThe rules for B are the same as for A. A lacked A or B makes the donor's red cells react, which is the ABO rule, and a lacked D is described as a risk of sensitisation and not as an immediate reaction, which is why it is a conclusion of its own. The next program writes all sixty-four pairs of the eight groups and asks, for each donor, which recipients the rules find no fault with:
import body
groups = ["O-", "O+", "A-", "A+", "B-", "B+", "AB-", "AB+"]
for i in range(8):
for j in range(8):
body.transfusion("t" + str(i) + str(j), groups[i], groups[j], "every pair")
for i in range(8):
fine = []
for j in range(8):
v = body.verdict("t" + str(i) + str(j))
if len(v) == 0:
fine = fine + [groups[j]]
print(groups[i], fine)O- ['O-', 'O+', 'A-', 'A+', 'B-', 'B+', 'AB-', 'AB+']
O+ ['O+', 'A+', 'B+', 'AB+']
A- ['A-', 'A+', 'AB-', 'AB+']
A+ ['A+', 'AB+']
B- ['B-', 'B+', 'AB-', 'AB+']
B+ ['B+', 'AB+']
AB- ['AB-', 'AB+']
AB+ ['AB+']The table is the one in the textbooks. Group O red cells can be given to any ABO group, and the people of group AB can receive red cells from any group. O-negative blood is often called universal donor blood and AB-positive universal recipient blood, and the page that says so calls the terms only generally true, with respect to the recipient's anti-A and anti-B antibodies: the Bombay phenotype is an exception, since such people can receive blood only from donors of their own kind. The first row is the library's reading of that and the last row its other half. A positive donor can give only to positive recipients, in this table, because a D-negative recipient would be at risk of sensitisation.
The library does not leave the rules at a yes or a no, and it keeps a pair that fails, with what failed:
import body
body.transfusion("o_to_ab", "O-", "AB+", "ward")
body.transfusion("ab_to_o", "AB+", "O-", "ward")
body.transfusion("a_to_a", "A+", "A-", "ward")
print(body.verdict("o_to_ab"), body.verdict("ab_to_o"), body.verdict("a_to_a"))
print(body.lacks("o_to_ab"), body.lacks("ab_to_o"), body.lacks("a_to_a"))
n = why_not(body.Transfusion.a_to_a.reacts)
for line in str(n).split("\n"):
print(line)
body.transfusion("a_to_a", "A+", "A+", "a second reading")
print(body.verdict("a_to_a"), body.unsettled())[] ['reacts', 'sensitises'] ['sensitises']
[] ['A', 'B', 'D'] ['D']
rule `body.reacts_for_a` needs body.Transfusion[a_to_a].lacks_a == True, and nothing is recorded there
rule `body.reacts_for_b` needs body.Transfusion[a_to_a].lacks_b == True, and nothing is recorded there
['sensitises'] ['transfusion a_to_a rd']O-negative to AB-positive lacks no antigen, and AB-positive to O-negative lacks all three, so it reacts and it sensitises. A-positive to A-negative lacks only D: it sensitises and does not react, and the why_not of the reaction names the two ways it could have happened, a lacked A and a lacked B, and says that nothing is recorded for either. Then a second source gives the recipient as A-positive. Both readings are kept, unsettled() names the fact they disagree about, which is the recipient's D, and the verdict is still sensitises, because a conclusion stands if any reading on record supports it. What the library keeps is that it is a disagreement, and no query refuses.
Transfusion became practical in steps after the groups were known. After the groups were discovered donor and recipient blood were mixed beforehand as an early form of cross-matching, and in 1915 Rous and Turner reported that testing compatibility in advance could prevent clumping. In 1914 Hustin and Agote used sodium citrate as an anticoagulant, so that blood no longer had to pass directly from one person to another, and in 1917 Oswald Hope Robertson set up early blood banks for the Western Front. Bernard Fantus founded the first hospital blood bank in the United States, at Cook County Hospital in Chicago, in 1937, and he is credited with the term "blood bank". The library knows none of this testing, and it says so: matching in practice is done in a laboratory, by testing the blood of donors and recipients and by cross-matching, and plasma, platelets, the Kell and other systems and a rare group are outside the rules.
2. Body size
The index that doctors and the press call BMI is older than its name. Adolphe Quetelet, a Belgian astronomer, mathematician and statistician, devised its basis between 1830 and 1850 as part of a study of the "average man", and it was called the Quetelet index. He did not intend it for medical assessment and never meant it to judge the health of individuals. The name came in July 1972, in a paper in the Journal of Chronic Diseases by Ancel Keys and others, who called it, "if not fully satisfactory, at least as good as any other relative weight index as an indicator of relative obesity". Keys judged it appropriate for population studies and not for the evaluation of individuals. It is the mass in kilograms over the square of the height in metres, and the library gives each person the figure, worked out from the mass and the height:
bmi: real = kg / metres / metres
underweight: bool = bmi < 18.5
overweight: bool = bmi >= 25.0
obese: bool = bmi >= 30.0The World Health Organization treats an index under 18.5 as underweight, 25 or more as overweight and 30 or more as obese, and the range between, from 18.5 up to but not including 25, is normal. The library concludes that last band with a rule of its own, and the others it states as fields. The cut-offs are not the same everywhere. The WHO also identified additional points of risk for Asian populations, at 23, 27.5, 32.5 and 37.5, and Japan starts its first class of obesity at 25. Six people of one height show the bands, with the boundary at 25 and a person with a height of zero:
import body
body.person("light", 50.0, 1.75)
body.person("middle", 70.0, 1.75)
body.person("heavy", 90.0, 1.75)
body.person("heaviest", 100.0, 1.75)
body.person("edge", 76.5625, 1.75)
body.person("nobody", 70.0, 0.0)
for name in ["light", "middle", "heavy", "heaviest", "edge", "nobody"]:
print(name, round(body.bmi(name), 2), "[" + body.band(name) + "]")
n = why_not(body.Person.nobody.bmi)
print(n)
body.person("middle", 80.0, 1.75)
print(round(body.bmi("middle"), 2), body.band("middle"))light 16.33 [underweight]
middle 22.86 [normal]
heavy 29.39 [overweight]
heaviest 32.65 [obese]
edge 25.0 [overweight]
nobody 0.0 []
rule `body.Person.bmi` has everything it requires, but its conclusion computes 70.0 / 0.0, which has no answer — body.Person[nobody].kg is 70.0 and body.Person[nobody].metres is 0.0 — so the conclusion is not drawn
26.12 overweightThe 76.5625 kilograms of the person called edge is 25 times the square of 1.75 exactly, and 25.0 is overweight: the band is closed at the bottom and open at the top, as the WHO's is. The person with no height has no index. The conclusion has no answer, so none is drawn, no band is concluded, and why_not says that it would divide by zero. The library's reader gives 0.0 for a missing index and an empty string for the band. The last pair is a correction: the person called middle is written again at 80 kilograms, and the old figure and the band that rested on it are gone.
The critique of the index is as well known as the index. It overestimates adiposity in lean people such as athletes and underestimates excess fat in others, and it does not distinguish the fat under the skin from the fat around organs. A 2008 study of survey data found obesity in 21% of men and 31% of women by BMI, against 50% and 62% by body fat, a sensitivity of 36% and 49% with a high specificity. Quetelet's data came mostly from Scottish Highland soldiers and French gendarmes, and the scale was designed for European men. The page on the index cites the waist-to-height ratio and waist–hip measures as sometimes better predictors of risk. The band in the library is a statement of the WHO's definition, and the library, like the index, makes no judgement of a person.
3. Energy, surface and the heart
Three more numbers in the library are formulas from the literature, each an estimate. The resting energy is the rate of energy expenditure of a body at rest, measured in a person who is undisturbed, in a thermally neutral place and not digesting food. Harris and Benedict published a pair of equations in 1918 and 1919 that estimated it from mass, height and age, because accurate measurements of body composition were difficult to obtain then. In 1990 Mifflin and St Jeor published another, and a later study by Frankenfield and others found it to be about 5% more accurate. It is ten times the mass in kilograms, plus 6.25 times the height in centimetres, minus five times the age in years, plus 5 for a male or minus 161 for a female:
base = 10.0 * kilograms + 6.25 * height_cm - 5.0 * age_years
return base + 5.0
return base - 161.0The body surface is used because it is a better indicator of metabolic mass than body weight, and it is less affected by abnormal fat mass. It is the basis of the cardiac index, the cardiac output divided by the surface, and of dosing in some treatments, though the page on it notes that dosing by surface has been criticised for drugs of a narrow therapeutic index. Du Bois published his formula in 1916, and Mosteller's of 1987 is mathematically simpler: the square root of the height in centimetres times the mass in kilograms over 3600.
p = height_cm * kilograms
return math.sqrt(p / 3600.0)Where the product of the two would pass the largest real, or fall below the smallest, the library takes the root of each and divides by 60 instead, which is the same quantity.
The maximum heart rate is a different kind of estimate, because its history is an unusual one. "220 minus the age" is the formula of Haskell and Fox, dated 1971 in the table of the page and 1970 in its text, and it was not derived from original research: they plotted data from about eleven published or unpublished sources. Its standard deviation is 12 to 15 beats a minute. Tanaka, Monahan and Seals published a formula in 2001 from the results of 315 studies and 514 individuals, 208 minus 0.7 times the age, with a standard deviation of about 10. The page on the heart rate says of such formulas that they "may deviate significantly from the actual value", because they give only generalised averages of populations.
return 220.0 - age_years
return 208.0 - 0.7 * age_yearsimport body
print(body.mifflin_st_jeor(59.0, 168.0, 55.0, False), body.mifflin_st_jeor(59.0, 168.0, 55.0, True), body.mifflin_st_jeor(80.0, 180.0, 40.0, True))
print(round(body.body_surface_mosteller(59.0, 168.0), 3), round(body.body_surface_mosteller(80.0, 180.0), 3))
for age in [20.0, 40.0, 60.0]:
print(age, body.max_heart_rate_haskell_fox(age), round(body.max_heart_rate_tanaka(age), 1))
print(round(body.body_mass_index(80.0, 1.8), 2))1204.0 1370.0 1730.0
1.659 2.0
20.0 200.0 194.0
40.0 180.0 180.0
60.0 160.0 166.0
24.69The first value is the worked example of the account of the equation: a woman of 55 years, 59 kilograms and 168 centimetres, for whom the Mifflin and St Jeor formula gives 1,204 kilocalories a day, and the original equation of Harris and Benedict gives 1,272. The same body, taken to be male, would have 1,370 by the formula, since the sex enters only as the constant. The surface of that body is 1.659 square metres, and that of a person of 80 kilograms and 180 centimetres is 2.0. For comparison, the page on the surface reports an average of 1.73 square metres in a series of 3,000 cancer patients, and means of 2.060 for men and 1.830 for women from a United States survey. The two heart-rate formulas agree at the age of 40, at 180 beats a minute, and part on either side of it: the older formula is higher for the young and lower for the old. A person's own maximum may be well away from both, by the deviations of 10 and 12 to 15 beats a minute that the sources state, and the arithmetic cannot tell which side.
4. What the library leaves out
The library leaves out most of what a body is. There is no plasma or platelet compatibility, no Kell or other blood system, no rare group, no children's growth, and no dose. The rules are the rules taught in introductions, and the first thing a clinic does is test. A body mass index is computed for an adult by a definition that its namer judged unfit for individual use, and the bands it draws are bands of the WHO. The two formulas for the resting energy of an adult and for the maximum heart rate are estimates of populations, and the library does not say which is right for a person. It gives the same digits every time to everyone who runs it, and a reader who wants to know what applies to a body should ask someone who has examined it.
Closing
Much of what the library holds is a history of replacing luck with a rule. Denys and Blundell transfused without knowing why some patients lived. Landsteiner's letters turned luck into a rule, Rous and Turner reported that testing in advance could prevent clumping, and Fantus gave the system a bank. Quetelet counted the average man, and his index outlived his purpose; Haskell and Fox plotted data from about eleven sources, and their formula outlived the plot. The library keeps these procedures where a reader can run them and ask about them. It names the antigen a donor's red cells carry and a recipient's lack, draws no index for a height of zero and says why, and holds two readings of one fact side by side when sources differ. And because each conclusion names the facts it rests on, a group corrected in one place is corrected in every verdict that rested on it.