Source code for frontline
"""
Script to estimate the amount of time that Dr. Bruce Ivins spent at USAMRIID
outside of normal work hours, based on his swipe access records at the "rear"
door. Analysis performed for PBS Frontline's "The Anthrax Files".
Usage: python frontline.py
Author: Elaine Angelino <elaine at eecs dot harvard dot edu>
Copyright 2011
"""
import datetime
import numpy as np
import tabular as tb
weekday_dict = dict(zip(range(7), ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']))
[docs]def str2weekday(x):
"""
Helper function to get the day of the week corresponding to a given date.
"""
(m, d, y) = x.split('/')
return weekday_dict[datetime.date(int(y), int(m), int(d)).weekday()]
[docs]def str2min(x):
"""
Helper function to convert a time into the number of minutes since midnight.
"""
(h, m, s) = x.split(':')
return int(h)*60 + int(m)
[docs]def plot_hours(fin='door-5pm-7am.tsv', fout='ivins-extra-hours-2001.pdf'):
"""
Bar chart summarizing estimated time Dr. Bruce Ivins's worked after hours.
Estimated time Dr. Bruce Ivins spent at USAMRIID after hours. The total
number of hours is plotted for each month in 2001. Note that the anthrax
attacks occurred for several weeks, starting on September 18, 2001.
Disclaimer: I performed this analysis in November 2011. It was not a part
of PBS Frontline's analysis for "The Anthrax Files".
"""
import calendar
import pylab
x = tb.tabarray(SVfile=fin)
x = x[['date_in', 'total_time']]
recs = [[int(i) for i in d.split('/')] for d in x['date_in']]
dates = tb.tabarray(records=recs, names=['month', 'day', 'year'])
assert len(set(dates['year'])) == 1
y = x[['total_time']].colstack(dates[['month']])
z = y.aggregate(On=['month'])
z.sort(order=['month'])
ind = np.arange(len(z))
pylab.clf()
pylab.bar(ind, z['total_time'] / 60)
xt = [calendar.month_name[m][:3] for m in z['month']]
pylab.xticks(ind + 0.4, xt)
pylab.title('Estimated time Dr. Bruce Ivins spent at USAMRIID after hours')
pylab.xlabel('Month (in 2001)')
pylab.ylabel('Number of hours')
pylab.savefig(fout)
if __name__ == '__main__':
compute_extra_hours()