Homework Assignment 4, 6.872/HST950

Handed out: April 30, 2004
Due in: May 13, 2004

Note that both this last homework assignment and your write-ups for class projects are due on the last day of classes, May 13.  Those who are presenting their projects early can afford to work on this homework problem after their presentations.  If you are presenting late, however, you should make sure that you substantially complete this assignment before your project.

Building a Web-based EMR

For this problem, we ask you to explore techniques for how to build a Web-based electronic medical record system.  The purpose of the assignment is to convince you, through personal experience, that it is not immensely difficult to do at least a simple job of building such a system, and that the power of the Web and the availability of Web resources makes you very powerful.  To keep the assignment within bounds, we make the following assumptions:

Warning:  We do assume that you have had some experience building Web sites, and in particular that you understand something about HTML.  If not, now is a good time to learn about it:  See the W3C's documentation.

Installation

The first (painful) step in doing this assignment is to install everything you need to run it.  We have prepared a single .zip file that contains most of what you should need, at least if you are running on Windows XP.  You will need about 130MB of free disk space.  Here are the steps to this:

  1. Make sure you have the java sdk (System Development Kit) installed. If not, download and install J2SE v 1.4.2_04 SDK from this URL:  http://java.sun.com/j2se/1.4.2/download.html.
  2. Unzip 6872hw4.zip to the root directory of your C drive, i.e. C:\.
    You will see two new directories: c:\mysql and c:\resin-ee-3.0.7
  3. Start the database server, mysql, by running:

    c:\mysql\bin\mysqld-nt

    You will need to run this command every time you log in or restart windows. If you don't want this hassle, you can install mysql as a service, which automatically starts whenever Windows reboots, by running:

    c:\mysql\bin\mysqld-nt --install

    Note: you need administrator privileges to install a service on windows. The database and access privilege setting are already tailored for this homework.

    If you want to log into mysql, you can do so either anonymously or use root, which has a password "6872"

  4. Start the Web server, Resin, by running:

    c:\resin-ee-3.0.7\bin\httpd

    You will need to run this command every time you log in or restart windows. If you don't want this hassle, you can install Resin as a service, which automatically starts whenever windows reboot, by running:

    c:\resin-ee-3.0.7\bin\httpd -install

    Note: you need administrator privilege to install a service on windows.
  5. Now the system shall be ready to use. You can try the demo at this URL:

    http://localhost:8080/demo

  6. You can start writing your own code and putting it in c:\resin-ee-3.0.7\webapps\cws\. Then you can run a file such as foo.jsp via a URL such as:

    http://localhost:8080/cws/foo.jsp

    Our "starter code" is located at http://localhost:8080/cws/index.jsp, which is also what you get if you simply go to the URL http://localhost:8080/cws/.  This is what you will modify in the homework.

If the above instructions did not work for you, you will have to go through the more detailed and painful detailed installation instructions and follow the steps carefully.

Explore

First, connect to your skeletal server and note the functionality that we initially provide.  The main server page simply lists all the patients in the CWS database alphabetically, along with their "PAT_NUM" identifiers.  Each name links to a (dynamic) page that will display information specific to that patient.  In the skeleton, this includes only demographics and the problem list, though obviously much other data also exists in the CWS database about these patients.

Take a look at the index.jsp source code for the top page of the site:

<h1>CWS Database</h1>
<table border="0" cellspacing="5">
<tr><th>#</th><th>Patient</th></tr>

<%
SqlAccess s = null;
try {
    s = new SqlAccess("jdbc/cws");

    List people = s.retrieveAll("select pat_num,last_name,first_name,title as mid_initl from pat_demograph order by last_name,first_name,mid_initl");

    Iterator it=people.iterator();
    while (it.hasNext()) {
        Entity b = (Entity)it.next();

        EnglishName n = new EnglishName(b.getS("last_name"),
                                        b.getS("first_name"),
                                        b.getS("mid_initl"));

        out.write("<tr><td align=\"right\">" + b.getS("pat_num")
                + "</td><td><a href=\"pt.jsp?id=" 
                + b.getS("pat_num") + "\">"
                + n.toString()
                + "</a></td></tr>\n");
    }
}
finally {
    if (s!=null) s.close();
}
%>
</table>

This code uses three utility classes defined in the DBWeb package:

  1. SqlAccess: encapsulates connection and access to the database.  Provides methods retrieve and retrieveAll that return the results of a SQL query.  Retrieve yields an Entity, and retrieveAll yields a List of Entities.
  2. Entity: An association-list that is used to represent rows from a relational data base, field names/contents from an HTML form, etc.  get retrieves the value associated with its argument, which is a String.  getS is like get, but yields an empty string instead of a null.  getH is like getS, but "HTML-encodes" its contents (e.g., "<" turns into "&lt;").  getMdyDate and getSqlDate turn various formats of date strings into 12/31/1999-style and 1999-12-31-style dates.
  3. EnglishName: Understands structured forms of English-style names, which can be constructed from their parts or by parsing a string containing the whole name.  toString and toFNF return the "Smith, Joseph" and "Joseph Smith" versions.  getXXX and setXXX methods exist for each part of the name: first, last, middles, vons, and suffix.  This is modeled on BibTeX's analysis of names.

The code above creates a SqlAccess object s that holds the database connection.  The call to retrieveAll selects name parts and patient number from the patient demographics table.  We then iterate over all the elements of this list.  For each one, we create an EnglishName object, and output to the HTML page being constructed one row of a table, which holds the patient number, the last-name-first version of the name, and a hyperlink to pt.jsp with this patient number as the id argument.  (Note that "title as mid_initl" solves an apparent database bug, whereby patients' middle initials are stored under "title".)

The classes described briefly above form part of a lightweight framework for building Web-based applications whose background data are stored in a database.  This framework is described in greater detail here.

You can examine the files referenced above:

Because at this point you should have all the software installed on your computer, you can of course also use your favorite editor to examine any part of the framework or example code.

Improve PubMed access

You will see in pt.jsp that for any patient who has problems associated with his/her case, our skeleton code has hyperlinked each problem name to a complex URL at the National Library of Medicine's PubMed that shows the user "systematic review articles" about the name of the problem.  If you look at the NLM's site that this code uses, http://www.ncbi.nlm.nih.gov/entrez/query/static/clinical.html, you will see that in fact there are also a number of other "research methodology filters" that allow one to search for therapy, diagnosis, prognosis and etiology-related articles about the topic, and for each of these, to emphasize sensitivity or specificity.  Interestingly, the filters are actually relatively simple, but have been shown in the Haynes reference to do a good job.  Hint: Where did I get the large URL embedded in pt.jsp, and the other one in the comment near the end of that file?

Implement an extension to the display generated by pt.jsp that allows the user to determine which of the five kinds of retrieval PubMed is to perform on the text of the problem name.  Think about how your user would perceive various ways you might design and implement this, and argue why you have chosen your approach.

Add Laboratory lookup

The table pat_test_histv contains all the in-house Lab values measured.  Design and implement an interface that provides high-level navigation tools to allow a user to look up labs for a specific patient either chronologically (e.g., all lab values measured today) or organized as time series by the quantity measured (e.g., the sequence of serum creatinine values ever measured).  Because this table has indications of which values are "normal" or not, be sure you indicate this visually.  Note: This is certainly an open-ended problem, but I urge you to spend only a limited amount of time on it, and focus on what you consider interesting design issues.  For example, you may be tempted to graph various values; unless you are either a wizard Java Applet programmer or have a handy toolkit available, resist the temptation.

Making changes

Using the demo classes/professors database that was described in the framework writeup as an example, build a very simple web page that, for a given patient, shows and allows you to modify the providers who act as providers for this patient.  You should also provide a way for a user to reach this page from pt.jsp.  Don't worry about authorization to make such changes, which would be a concern in an actual operating hospital.

Food for Thought

Looking at the rest of the data in CWS, briefly outline what additional capabilities it could support toward having a complete browser for an EMR.  This should be just design, not implementation.  Estimate how much effort it would take you to actually build it.


psz@mit.edu, 04/30/2004