Saturday, March 28, 2009

Arduino Library for Processing

I have already done some work with Arduino and C#.NET in an earlier post and now decided to extend the work to Java as well with the Processing software. For example, at http://www.arduino.cc/playground/Interfacing/Processing they provide the following Processing code:

import processing.serial.*;
import cc.arduino.*;
Arduino arduino;
int ledPin = 13;
void setup()
{
//
println(Arduino.list());
arduino = new Arduino(this, Arduino.list()[0]);
// v2
//
arduino = new Arduino(this, Arduino.list()[0], 57600);
// v1
arduino.pinMode(ledPin, Arduino.OUTPUT);
}
void draw()
{
arduino.digitalWrite(ledPin, Arduino.HIGH);
delay(1000);
arduino.digitalWrite(ledPin, Arduino.LOW);
delay(1000);
}

that can be exported to an executable jar. Futhermore, the provide the Arduino jar and source code to control the board from Processing. A nice vehicle for getting up to speed quickly with Arduino applications. For other languages beside Java and C#, refer to http://www.arduino.cc/playground/Main/InterfacingWithSoftware .

Thursday, March 19, 2009

AML-Agent Modeling Language and StarUML

Agent Modeling Language(AML) is a visual modeling language that uses the concepts of Multi-Agent Systems (MAS) theory for specification and modeling of agents. For more information, please consult that paper at http://www.whitestein.com/library/whitestein_aml-specification_v09.pdf . The AML profiler can be downloaded for StarUML at http://www.whitestein.com/library/company-and-product-resources#methodology .

Figure 1. StarUML with an AML Example


Figure 1. shows the StarUML interface with an example AML. One of the features that I like is the modeling of ontologies for the agent. Figure 2. shows a medical example.
Figure 2. Example of an OntologyClass


Clearly, AML in StarUML offers some nice possibilities and demands further investigation. I recommend using it for modeling your agent based systems.

StarUML for Generating Java, C#, C++ code

This morning as I was doing research on building bridges to ontologies based on semantic distance and I thought about using StarUML to develop the UML products that I need for both my papers, books, projects and grant work. In the past, I used Visio for such things, but I wanted to do something different and be more immersed into the open source world. Here at http://sourceforge.net/project/screenshots.php?group_id=152825 you can download the application from Sourceforge.net. Figure 1 shows the UI.

Figure 1. StarUML with SVD C# Class

I decided to try out the application by reverse engineering a C# singular value decomposition class that I am modifying for another research paper. Below is a sample of the code generated from the class.
//
//
// Generated by StarUML(tm) C# Add-In
//
// @ Project : Untitled
// @ File Name : SingularValueDecomposition.cs
// @ Date : 3/19/2009
// @ Author :
//
//

public class SingularValueDecomposition {
private double[][] U ;
private double[][] k;
private double[][] V ;
private double[] s ;
private int m ;
private int z;
private int n ;
public SingularValueDecomposition(GeneralMatrix Arg){
}
private double[] SingularValues{
get{
}
}
private GeneralMatrix S{
get{
}
}
public virtual GeneralMatrix GetU(){
}
public virtual GeneralMatrix GetV(){
}
public virtual double Norm2(){
}
public virtual double Condition(){
}
public virtual int Rank(){
}
private void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context){
}
}

The application works but as you can see sometimes the code needs to be edited, but it does support UML 2.0. I am going through and looking at the bugs in the reverse engineering part. Since the source code is available-written in Delphi, it provides an opportunity to make changes to the application. For a full list of features, consult http://staruml.sourceforge.net/en/about-2.php . As you can see, there are many possible enhancements that can aid in the development of code. I plan to now use this for my UML artifacts.

Tuesday, March 17, 2009

Hidden Markov Models-Part 2

In a previous post in January on HMM, I mentioned the work of Jean-Marc Francois at http://code.google.com/p/jahmm/wiki/Overview with respect to building Hidden Markov Models (HMM) with his java library jahmm.jar. Of course, my interest in HMM is for these domains:
  • Speech recognition
    M. T. Chan, "HMM-based Audio Visual Speech Recognition Integrating Geometrics andAppearance-based Visual Features," presented at IEEE Workshop on Multimedia Signal Processing, Cannes, France, 2001.


  • Bioinformatics / Genomics
    Thomas Plötz, GernotA. Fink,"Pattern recognition methods for advanced stochastic protein sequence analysis using HMMs", Pattern Recognition, Volume 39, 2006


  • Robotics (robot sensing)
    Sven Koenig and Reid Simmons, A Robot Navigation Architecture Based on Partially Observable Markov Decision Process Models," in Artificial Intelligence Based Mobile Robotics:CaseStudies of Successful Robot Systems, D. Kortenkamp, R. Bonasso, and R. Murphy, Eds., pp. 91-122. MIT press, 1998.


  • Economics / Finance
    Rossi, Alessandro & Gallo, GiampieroM., 2006. "Volatility estimation via hidden Markov models," Journal of Empirical Finance, Elsevier, vol. 13(2), pages 203-230,

Here is his example of building a HMM with known parameters, generating a sequence of observations with the HMM, learning parameters, and computing probabilities for a coin flipping experiment. We can use the K-means to initialize the HMM and then use Baum-Welch to optimize. The dot file used in both of these cases can be converted to graph through the graphViz package. The Viterbi algorithm can be used for making predictions about the most probable state given the sequence of observations.

import java.util.*;
import be.ac.ulg.montefiore.run.jahmm.*;
import be.ac.ulg.montefiore.run.jahmm.toolbox.*;
import be.ac.ulg.montefiore.run.jahmm.learn.*;
import be.ac.ulg.montefiore.run.jahmm.draw.*;

public class HMM_CoinFlip {static public void main(String[] argv) throws java.io.IOException {
/*populate the data with N sequences of J binary coin flips, e.g. {{0,1,....,J},....,{0,1,...,J}}
int[][] data ={{}};
/* Read data into sequences */
Vector sequences = new Vector();
for (int i = 0; i < sequence =" new" j="0;" obs =" new" kml =" new" inithmm =" kml.learn();" bwl ="new" learnthmm =" bwl.iterate(initHmm);" i =" 0;" learnthmm =" bwl.iterate(learntHmm);}" http://www.biomedcentral.com/content/pdf/1471-2164-9-S1-S8.pdf and looked at their use of JahmmVix and GHMM Hidden Markov Model Editor. JahmmViz is the GUI for the library which uses Jung- a graph drawing library. The GUI can be obtained by using Java Web Start at
http://www.run.montefiore.ulg.ac.be/~francois/software/jahmm/jahmmViz/#use . GHMM can be downloaded at http://ghmm.sourceforge.net/hmmed.html and Java Web Started at http://casp.rnet.missouri.edu/hmmeditor/ . The User's manual is at http://casp.rnet.missouri.edu/hmmeditor/manual/HMMVE_1.1_manual.pdf.

Currently, I am experimenting with these libraries and will post more on my findings with some prototypes as I continue to assemble components together for this architecture.

Friday, March 13, 2009

NIH Funding-Part 2:Reading an RSS Feed in Java

In Part 1, I showed how to write an RSS Feed. Here I show how to use Java to read an RSS feed from the NIH link at http://grants.nih.gov/grants/guide/newsfeed/fundingopps.xml .

Step 1: The RSS Reader and Testing the Code

public class XmlRSSReader
{
public XmlRSSReader() {
try {
Builder bd = new Builder();
Document doc = bd.build("fundingopps.xml");
// Get the file's root element
Element root = doc.getRootElement();
Element channel = doc.getFirstChildElement("channel");
// Get its title element
Element title = channel.getFirstChildElement("title");
Text titleText = (Text)title.getChild(0);
Elements NIHs = root.getChildElements("item");
for (int i = 0; i < NIHs.size(); i++)
Element NIH = NIHs.get(i);
// Look for a title element inside it
Element itemTitle = NIH.getFirstChildElement("title");
// If found, look for its contents
if (itemTitle != null) {
Text itemTitleText = (Text) itemTitle.getChild(0);
// Good place to search the text
// do something
if (itemTitleText.toString().indexOf(searchTerm) == -1)
//do something
}
// Get all child elements of
Elements children = NIH.getChildElements();
for (int j = 0; j < children.size(); j++) {
Element child = children.get(j);
Text childText = (Text) child.getChild(0);
if (childText != null) {
System.out.print(child.getLocalName());
System.out.print(": ");
System.out.print(childText.getValue());
System.out.println("");
}

Step 2: Test the Code

public static void main(String[] arguments) {
XmlRSSReader xrss = new XmlRSSReader();
}
}

Clearly, we can combine RSS feeds and search for items on elements such as titles to build lists of common funding opportunities to reseachers.

Wednesday, March 11, 2009

NIH Funding-Part 1:Write an RSS Feed in Java

I wanted to be able to both read and write with RSS for examining NIH, NSF and other possible funding opportunities. In Part 1, I examine how to write a RSS read. The NIH link and a sample RSS Feed for the NIH is at http://grants.nih.gov/grants/guide/newsfeed/fundingopps.xml. My first step is to be able to create RSS Feeds like the one above in Java. Here I build on the work by http://www.vogella.de/articles/RSSFeed/article.html for the code.

Step 1: The Grant Model : RSSTest

package rss.grantmodel;

public class RSSTest
{
String title;
String description;
String link;
String researcher;
String guid;
String grant;
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getGrant(){ return grant;}
public void setGrant(String grant){this.grant=grant;}
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public String getLink() { return link; }
public void setLink(String link) { this.link = link; }
public String getResearcher() { return researcher; }
public void setResearcher(String researcher) { this.researcher = researcher; }
public String getGuid() { return guid; }
public void setGuid(String guid) { this.guid = guid; }
}

Step 2: RSSFeedItem

package rss.grantmodel;

import java.util.ArrayList;
import java.util.List;

public class RSSFeedItem{
List entries = new ArrayList();
String channel;
String title;
String link;
String description;
String language;
String copyright;
String pubDate;

public List getEntries() {
return entries; }
public void setEntries(List entries)
{ this.entries = entries; }
public String getTitle()
{ return title; }
public void setTitle(String title)
{ this.title = title; }
public String getLink()
{ return link; }
public void setLink(String link)
{ this.link = link; }
public String getDescription()
{ return description; }
public void setDescription(String description)
{ this.description = description; }
public String getLanguage()
{ return language; }
public void setLanguage(String language)
{ this.language = language; }
public String getCopyright() { return copyright; }
public void setCopyright(String copyright) { this.copyright = copyright; }
public String getPubDate() { return pubDate; }
public void setPubDate(String pubDate) { this.pubDate = pubDate; }

Step 3: Create the XML Writer

package rss.writefeed;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import rss.grantmodel.RSSTest;
import rss.grantmodel.RSSFeedItem;

public class RSSFeedWriter
{
private String outputFile;
private RSSTest rssfeed;
public void setFile(String configFile) { this.outputFile = configFile; }
public void setRssfeed(RSSTest rssfeed) { this.rssfeed = rssfeed; }
public void write() throws Exception {
// Create a XMLOutputFactory
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
// Create XMLEventWriter
XMLEventWriter eventWriter = outputFactory .createXMLEventWriter(new FileOutputStream(outputFile));
// Create a EventFactory XMLEventFactory
eventFactory = XMLEventFactory.newInstance();
XMLEvent end = eventFactory.createDTD("\n");
// Create and write Start Tag
StartDocument startDocument = eventFactory.createStartDocument();
eventWriter.add(startDocument);
// Create open tag
eventWriter.add(end);
StartElement rssStart = eventFactory.createStartElement("", "", "rss");
eventWriter.add(rssStart);
eventWriter.add(eventFactory.createAttribute("version", "2.0"));
eventWriter.add(end);
eventWriter.add(eventFactory.createStartElement("", "", "channel"));
eventWriter.add(end);
// Write the different nodes
createNode(eventWriter, "title", rssfeed.getTitle());
createNode(eventWriter, "link", rssfeed.getLink());
createNode(eventWriter, "description", rssfeed.getDescription());
createNode(eventWriter, "language", rssfeed.getLanguage());
createNode(eventWriter, "copyright", rssfeed.getCopyright());
createNode(eventWriter, "pubdate", rssfeed.getPubDate());
for (Iterator iterator = rssfeed.getEntries().iterator(); iterator .hasNext();)
{
RSSFeedItem entry = (RSSFeedItem) iterator.next();
eventWriter.add(eventFactory.createStartElement("", "", "item"));
eventWriter.add(end);
createNode(eventWriter, "title", entry.getTitle());
createNode(eventWriter, "description", entry.getDescription());
createNode(eventWriter, "link", entry.getLink());
createNode(eventWriter, "researcher", entry.getReseacher());
createNode(eventWriter, "guid", entry.getGuid());
eventWriter.add(end);
eventWriter.add(eventFactory.createEndElement("", "", "item"));
eventWriter.add(end); } eventWriter.add(end);
eventWriter.add(eventFactory.createEndElement("", "", "channel"));
eventWriter.add(end);
eventWriter.add(eventFactory.createEndElement("", "", "rss"));
eventWriter.add(end);
eventWriter.add(eventFactory.createEndDocument());
eventWriter.close(); }

private void createNode(XMLEventWriter eventWriter, String name, String value) throws XMLStreamException
{
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
XMLEvent end = eventFactory.createDTD("\n");
XMLEvent tab = eventFactory.createDTD("\t");
// Create Start node
StartElement sElement = eventFactory.createStartElement("", "", name);
eventWriter.add(tab); eventWriter.add(sElement);
// Create Content Characters characters = eventFactory.createCharacters(value); eventWriter.add(characters);
// Create End node
EndElement eElement = eventFactory.createEndElement("", "", name);
eventWriter.add(eElement);
eventWriter.add(end); }}

Step 4: Test the Grant Model

package rss.main;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.Locale;
import rss.grantmodel.RSSTest;
import rss.grantmodel.RSSFeedItem;
import rss.writefeed.RSSFeedWriter;

public class Test {

public static void main(String[] args) {
// Create the rss feed
RSSTest rssFeedTest = new RSSTest();
// Add the information
rssFeedTest.setCopyright("Copyright by Jeff B. Cromwell");
rssFeedTest.setTitle("Grant Information");
rssFeedTest.setDescription("Grant Information");
rssFeedTest.setLanguage("en");
rssFeedTest.setLink(http://www.thecromwellworkshop.com/);
Calendar cal = new GregorianCalendar();
Date creationDate = cal.getTime();
SimpleDateFormat date_format = new SimpleDateFormat( "EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Locale.US);
rssFeedTest.setPubDate(date_format.format(creationDate));
//add one example item
RSSFeedItem feed = new RSSFeedItem();
feed.setTitle("RSSFeed");
feed.setDescription("This is a description");
feed.setAuthor(jbcromwell@thecromwellworkshop.com);
feed.setGuid("http://www.thecromwellworkshop.com/articles/RSSFeed/article.html");
feed.setLink("http://www.thecromwellworkshop.com/articles/RSSFeed/article.html");
rssFeedTest.getEntries().add(feed);
// Write the file
RSSFeedWriter writer = new RSSFeedWriter();
writer.setFile("articles.rss");
writer.setRssfeed(rssFeedTest);
try { writer.write(); }
catch (Exception e) { // e.printStackTrace(); } }
}

This can be easily extended to a servlet for the main method. This code enables us to generate a new RSS feed based on some categorical combination of funding sources. In Part 2, we will look at reading individual RSS feeds from different funding sources.

Thursday, March 5, 2009

Android: Mobile Device Applications

One of my students mentioned in class about the Android operating system for mobile devices that uses the Java programming language at http://code.google.com/android/. Applications are written in Java and bundled into an Android package that can be installed on mobile devices. For example, you can publish your app to the Android Market,

"Android Market is a hosted service that makes it easy for users to find and download Android applications to their Android-powered devices, and makes it easy for developers to publish their applications to Android users.

To publish your application on Android Market, you first need to register with the service using your Google account and agree to the terms of service. Once you are registered, you can upload your application to the service whenever you want, as many times as you want, and then publish it when you are ready. Once published, users can see your application, download it, and rate it using the Market application installed on their Android-powered devices.

To register as an Android Market developer and get started with publishing, visit the Android Market:
http://market.android.com/publish ".

I downloaded the sdk from http://developer.android.com/sdk/1.1_r1/index.html to get the android.jar to use with Eclipse. The HelloWorld example at http://developer.android.com/guide/tutorials/hello-world.html uses

package com.example.hello;
import android.app.Activity;
import android.os.Bundle;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

Youtube has some good videos on applications at http://www.youtube.com/watch?v=3LkNlTNHZzE show applications without borders. One of the great features is the com.google.android.maps and android.location which provides a spatial component for location based services such as resource tracking, proximity analysis and SMS messaging. Because it is written in Java, it is easy to interface with existing AI applications written in Java.

Wednesday, March 4, 2009

Drools: Java Rules Engine

Becuase of the commerical licensing issues with Jess, I wanted to look at an alternative source for my reasoning engines. As I mentioned in my last post on Jess, Drools is an open source rule engine at http://www.jboss.org/drools/ and implements the JSR94 API as well as an innovative semantics framework. A one minute tutorial is at http://legacy.drools.codehaus.org/1+Minute+DRL+Tutorial that shows DRL syntax, semantic modules-Base Semantic module and the Java semantic module. I like the example at http://www.theserverside.com/tt/articles/article.tss?l=Drools . I downloaded the binaries and attached both drools-core-4.0.7.jar and drools-compiler-4.0.7.jar as external jars to my project. The TestHelloWorldExample project in Eclipse is


import java.io.InputStreamReader;
import java.io.Reader;
import org.drools.RuleBase;
import org.drools.RuleBaseFactory;
import org.drools.StatefulSession;
import org.drools.audit.WorkingMemoryFileLogger;
import org.drools.common.DefaultAgenda;
import org.drools.compiler.PackageBuilder;
import org.drools.event.DebugAgendaEventListener;
import org.drools.event.DebugWorkingMemoryEventListener;
import org.drools.event.DefaultAgendaEventListener;
import org.drools.event.DefaultWorkingMemoryEventListener;
import org.drools.rule.Package;

public class TestHelloWorldExample {
/**
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
//read in the source
final Reader source = new InputStreamReader( TestHelloWorldExample.class.getResourceAsStream( "HelloWorld.drl" ) );
final PackageBuilder builder = new PackageBuilder();
//this wil parse and compile in one step
builder.addPackageFromDrl( source );
// Check the builder for errors
if ( builder.hasErrors() ) {
System.out.println( builder.getErrors().toString() );
throw new RuntimeException( "Unable to compile \"HelloWorld.drl\".");
}
//get the compiled package (which is serializable)
final Package pkg = builder.getPackage();
//add the package to a rulebase (deploy the rule package).
final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage( pkg );
final StatefulSession session = ruleBase.newStatefulSession();
session.addEventListener( new DebugAgendaEventListener() );
session.addEventListener( new DebugWorkingMemoryEventListener() );
final WorkingMemoryFileLogger logger = new WorkingMemoryFileLogger( session );
logger.setFileName( "log/helloworld" );
final Message message = new Message();
message.setMessage( "Hello World" );
message.setStatus( Message.HELLO );
session.insert( message );
session.fireAllRules();
logger.writeToDisk();
session.dispose();
}
public static class Message {
public static final int HELLO = 0;
public static final int GOODBYE = 1;
private String message;
private int status;
public Message() {
}
public String getMessage() {
return this.message;
}
public void setMessage(final String message) {
this.message = message;
}
public int getStatus() {
return this.status;
}
public void setStatus(final int status) {
this.status = status;
}
}
}

The input for the HelloWorld.drl given by:

package org.drools.examples
import org.drools.examples.TestHelloWorldExample.Message;
rule "Hello World"
dialect "mvel"
when
m : Message( status == Message.HELLO, message : message )
then
System.out.println( message );
modify ( m ) { message = "Goodbyte cruel world",
status = Message.GOODBYE };
System.out.println( message );
end
rule "Good Bye"
dialect "java"
when
Message( status == Message.GOODBYE, message : message )
then
System.out.println( message );
end

Combining these applications with the example provided above provides the foundation for using rules in an open source Java application.

Embedding Jess in Java for Agent Models

I am working with the reasoning mechanism for my agent models and decided to use the backward and forward chaining methods found in Jess at http://www.jessrules.com/ . I can embed Jess in Java with the following code once I add the jess.jar to the library in an IDE like Eclipse and ran the code below shown in Figure 1.


Figure 1. Java and Jess in Eclipse


import jess.Deffacts;
import jess.Fact;
import jess.JessException;
import jess.RU;
import jess.Rete;
import jess.Value;
/*
public class testJess {
/*

public static void main(String[] args) throws JessException {

String buff;
/*define instance for jess interface class*/
Rete engine = new Rete();
engine.batch("testFacts.clp");
engine.reset();
buff = "(facts)";
engine.eval(buff);
buff = "(assert (birthday Jeff))";
engine.eval(buff);/* execute it */
buff = "(facts)";
engine.eval(buff);
engine.run();
System.out.println("Happy Birthday");
buff = "(facts)";
engine.eval(buff);
/* define new fact (template using API*/
engine.eval("(deftemplate point (slot x) (slot y))");
Fact f = new Fact("point", engine);
f.setSlotValue("x", new Value(37, RU.INTEGER));
f.setSlotValue("y", new Value(49, RU.INTEGER));
engine.assertFact(f);
buff = "(facts)";
engine.eval(buff);
}
}

The working memory of Jess has three parts which contains the deftemplate that defines the different kinds of facts contained in the deffacts. Defrule defines the rules to operate on the facts. This is my testfile-testFacts.clp:

(printout t "First Jess in Java" crlf)
(deftemplate personal-data
(slot name)
(slot age)
(slot weight)
(slot height)
(multislot blood-pressure)
)


(deffacts people
(personal-data (name Jeff) (age 48) (weight 220)
(height 200) (blood-pressure 130 80))
(personal-data (name David) (age 20) (weight 170)
(height 100) (blood-pressure 200 40)))


(defrule birthday
?birthday <- (birthday ?name) ?data-fact <- (personal-data (name ?name) (age ?age)) =>
(modify ?data-fact (age (+ ?age 1)))
(retract ?birthday)
)

Using this example, one can build text files of templates, facts and rules to read by the Rete engine in Java. Other examples like Jess are open source rule engines such as

  • Drools
  • Hannurapi Rules
  • JEOPS
  • JRuleEngine
  • Mandarax
  • Open Lexicon
  • Prova
  • SweetRules
  • Take
  • Termware
  • Zionis

For more information, check out http://www.businessreviewonline.com/os/archives/2008/07/10_best_open_so.html . One example that uses the Rete engine is Drools at http://www.jboss.org/drools/ . More on this in the next post.

References

Friedman-Hill, E. (2003). Jess In Action: Rule Based Systems in Java. Greenwich, CT: Manning Publications.

Tuesday, March 3, 2009

Data Exchange Engines for EHR Systems

One of the new areas of research for The Cromwell Workshop is in the area of electronic health record research. Orlova (2005) has a nice article on 21st Century Healthcare Systems at http://www.pubmedcentral.nih.gov/articlerender.fcgi?artid=1560434 . The authors state in their abstract,

"An electronic health record - public health (EHR-PH) system prototype was developed to demonstrate the feasibility of electronic data transfer from a health care provider, i.e. hospital or ambulatory care settings, to multiple customized public health systems which include a Newborn Metabolic Screening Registry, a Newborn Hearing Screening Registry, an Immunization Registry and a Communicable Disease Registry, using HL7 messaging standards. Our EHR-PH system prototype can be considered a distributed EHR-based RHIE/RHIO model - a principal element for a potential technical architecture for a NHIN."

Their steps for an EHR-PH system protoype based on the HL-7 messaging standard involved tracking information from the hospital of birth to 4 public health programs:

Step 1. EHR-Birth Record
Step 2. Hearing Screening
Step 3. Newborn Screening
Step 4. Immunization
Step 5. Communicable Disease Reporting
Step 6. Healthcare Enterprise Viewer

They used a MVC framework in J2EE for their prototype. The openEHR foundation uses Java at http://www.openehr.org/downloads/publications/health_ict/Medinfo2007-openehr_java-ChenKlein.pdf for development. Wikipedia has a nice article on EHR at http://en.wikipedia.org/wiki/Electronic_health_record with open source software at http://en.wikipedia.org/wiki/List_of_open_source_healthcare_software.

In the course of consulting opportunities with GIS, SQL Server and .NET, another example is the South Carolina Birth Data Exchange Engine (BEE) Program which exchanges birth population data with users in both a timely and secure fashion. The “BEE” program builds on integrated/interoperable systems that permits multiple agencies and health care providers, i.e. for immunization and newborn screening, to directly share or access needed birth information for mission-critical public health practices.

This got me thinking about "How to select an EHR system" in 12 steps at http://www.aafp.org/fpm/20050200/55howt.html and with my degrees in economics, what is happening in medical economics at http://medicaleconomics.modernmedicine.com/memag/article/articleDetail.jsp?id=131518 . Furthermore, I looked at MediTech at http://www.meditech.com/Interoperability/ehrHome.htm with their interoperability and EHR initiatives. Finally, they have an interview on their Data Exchange engine at http://www.meditech.com/Interoperability/pages/1108fa_interview.htm .