#!/bin/sh

# Fact-checking the New Yorker's sensationalized presentation of some non-facts.
# See also:  https://twitter.com/1337p337/status/973821745546358784

# The calculations are pretty generous here.

# To use this script, you'll have to get the data and unzip it:
# https://www.cdc.gov/nchs/data_access/vitalstatsonline.htm#Mortality_Multiple
# To make sense of the offsets, you'll have to get this PDF:
# https://www.cdc.gov/nchs/data/dvs/Multiple_Cause_Record_Layout_2016.pdf
# Finally, to make sense of the codes used for various drugs and causes of
# death, you'll want to look here:
# http://apps.who.int/classifications/icd10/browse/2016/en

# Technical notes:
# I used mawk.  I know the 'cat' looks useless, but it's actually a cheap
# way to buffer.  Time the script if you don't believe me, but at least on my
# system, using cat makes it run a little faster than redirection or passing
# the file directly to mawk.

cat VS16MORT.DUSMCPUB | awk '
	BEGIN {
		# X40-X44 is accidental overdose.
		# X60-X64 is intentional (i.e., suicide)
		# Y10-Y14 is unknown intent.
		for(i = 0; i < 5; i++) {
			cs["X4" i]++
			cs["X6" i]++
			cs["Y1" i]++
		}
		for(i in cs)
			cs[i " "] = cs[i]
		# X85 is homicide; not by any stretch tied to the "opioid epidemic".
		# F11-F16 were phased out in 2008.  They were defined as "mental and
		# behavioral disorders due to psychoactive substance use", but
		# overdoses were reclassified as poisoning.

		# http://apps.who.int/classifications/icd10/browse/2016/en#/T36-T50
		opioids["T400"]++ # Opium
		opioids["T401"]++ # Heroin
		opioids["T402"]++ # Codeine, morphine
		opioids["T403"]++ # Methadone
		opioids["T404"]++ # Pethidine, a.k.a. Demerol
		opioids["T406"]++ # Other/unspecified narcotics.  (Generous)
	}

	{
		total++
		age_unit = substr($0, 70, 1)
		age = substr($0, 71, 3); age++;age-- # Overcome zero-padding
		icd = substr($0, 146, 4)
		if(age < 50 || (age_unit > 1 && age_unit < 9)) {
			u50t++
			if(cs[icd] && have_opioids()) {
				if(icd ~ /X4/)
					opioid_accident++
				else if(icd ~/X6/)
					opioid_intent++
				opioid_total++
			}
			else
				ocs[substr(icd, 1, 1)]++
		}
	}

	END {
			print "Causes that were not due to self-administered opioid OD:"
			for(i in ocs) {
				print i, "\t" ocs[i]
			}
			print "Total from accidental opioid overdose:", opioid_accident
			print "Total from intentional opioid overdose:", opioid_intent
			print "Total from opioid overdose:", opioid_total
			print "Total:", u50t
			print "Total, including over-50:", total
	}

	function have_opioids() {
		return substr($0, 344, 100) ~ /T40[012346]/
	}
'
