EMPI原始碼剖析(原創)

Ehowa發表於2014-12-11

Part source code of EMPI analyzing

1   PIX processand the deterministic matching

2.1    PixPdqServer.java

1.1.1              

Load IheActors.xmlwhich contains all the important IHE configurable information but springconfiguration XML, and Spring configuration xml is loaded by java class such asContext.java and others.

1.1.2              

Before click run ordebug in eclipse you should do run/debug configurations , click the argumentsand input ‘startup’ and the full path of IheActors.xml, so that the EMPI canrun as normal. But I am thinking how to deploy the javaproject and make it work normal not in eclipse.

1.1.3              

if the project isworking normally you can send message to it by 7 Edit and now the maincontroller is PixFreeHandler.java and it has been initialized, cause it iscalled by PixManager.

2.2    PixFreeHandler.java

1.2.1   

When send message by7 Edit, the handler will determine it whether can be processed that is themethod of booleancanProcess(Message theIn).and if it is ture into the Message processMessage(MessagemsgIn, String ip),and then if it is ADT_A01 into the Message processCreate(MessagemsgIn), and convert the message to HL7Header and get the MSH, then getthe PID and verify it in the database whether there is a domain exists, andother verifying such as bellow:

//Get the PID information and mathing it with the domainID of database.

PatientIdentifier patientId = getPatientIdentifiers(pid);

//verifying the device , domain , id of itself and the merge id

boolean isValidMessage = validateMessage(reply, hl7Header, patientId, null, true);

            if (!isValidMessage) return reply;

After the verifyingand into the method of main EMPI.

1.2.2   

Get patient form themessage by PatientgetPatient(Message msgIn), convert the PID to patient, and insert thepatient to the database before that the project will match the patient. matching= pixAdapter.createPatient(patient, header);

2.3    PersonManagerServiceImpl.java

1.3.1   

Person person =ConversionHelper.getPerson(patient) convert patient to person(frommessage of PID)  and

personAdded =Context.getPersonManagerService().addPerson(person) convertpatient to Patient Vist Infomation(from message of PVI).

1.3.2   

SecurityHelper.getSessionKey(); generate unique session id by tomcat Serve andupdate the information of this session but it does not work any more.

1.3.3  

Person personFound =findPersonUsingIdentifiers(person); verifying the existence of theperson in the database. if the result of the personFound is null then go intothe next method else throw exception.

1.3.4  

Generate the global id generateGlobalId(person); save theperson to the table of patient savePerson(person);

1.3.5  

Now into findAndProcessAddRecordLinks(person); method, it is usedto match the person with the person exists in the database and link with eachother if it is possible by the deterministic and the probabilistic matching.Actually this method is deterministic matching and just judge whether there isa person in the table of patient, if it is true and it will be linked and markwith full matching in 1.0 or the person will into the probabilistic matching.Now let’s into the deterministic matching firstly.

1.3.6  

The deterministic matching is throw the name and gender or others theadministrator can configure it by the system. The core is send sql: from Person p where p.name= ?1 and p.gender= ?2and p.id != ?3  ?1 and ?2 is the match filed and the ?3 is thematched person’s id. If the result is not null the matched person and theperson existed in the database will be cast into personLink object and linkwith each other and then saved to the table of patient_link .

1.3.7  

Get patient visit information(PVI) form message and save it to thetable of patient_visit.

1.3.8  

In the personManagerServiceImpl.java the process go to the last step ofthis:

// save audit event information                Context.getAuditEventService().saveAuditEvent(AuditEventType.ADD_PERSON_EVENT_TYPE, "Added a new person record", person);

And it will add this information to the table of audit_event in thedatabase.

1.3.9  

After all of this and then we will get into the PixFreeHandler.java forthe bellow:

//generate ACK message to back

HL7v231.populateMSA(reply.getMSA(), "AA", hl7Header.getMessageControlId());

//forward the PIX registration message and XDS registration

if ( Boolean.parseBoolean(Context.getSwitchService().getSwitchParams("switch.xdsregistry")) ) {

                    forwardToXdsRegistry(msgIn, patientId);

           }

//at the last make the audit log and PIX registration successfully.

auditLog(hl7Header, patient, AuditCodeMappings.EventActionCode.Create);

 ActuallyI don't’ understand the last 2 operation.

2 the probabilisticmatching of PIX

2.1    Preparationwork

2.1.1              

Before make matching we should get the fields for matching from thetable of database. And the fields are configurable in the database. When thesystem is starting all the fields are got from database cause these method arewrite in the initialized method and configured in the spring xml.

         2.1.2

After into findAndProcessAddRecordLinks(person); will dodeterministic matching firstly, If after send sql get the result is null andthe flag will not be changed and the flag is still true, so when judge the flagthe thread will into the method of probabilistic.

 

2.2    Begin

2.2.1

Load filtergroup information form the table of filtergroup , thefiltergroup is three recorders and they are firstname same, firstname like, andChinese name like. And the below the thread will make matching one by one.

Load filter information form table of filter, and these recorders arethe main algorithm and the weight, threshold and so on.

         2.2.2

Firstname same matching , create ahibernate’s criterion object firstly, and then combination the sql

(namein ('張三'))

                  

         2.2.3

Firstname like matching , create ahibernate’s criterion object firstly, and then the thread will get the name ofpatient from message and matching it , the patient’s first name will used tosend sql

selectnamefrom firstname t where t.code='zhan';

to oracle and get the so-calledlikely, and combination these names to a sql just like this

(namein ('張三', '昝三', '章三', '湛三', '臧三', '詹三'))

 

         2.2.4

Chinese name’s like matching , Ithink they actually want do it bu the code of Chinese font but cause somereasons they give up it and just combination a sql

(SUBSTR(name, 0, 1) like'%')

to oracle.

         2.2.5

                   Soall of these criterion convert to sql like this

select *

  from patient

 where (namein ('張三', '昝三', '章三', '湛三', '臧三', '詹三'))

    OR (SUBSTR(name, 0, 1) like'%')

    OR (namein ('張三'))

                  

 

 

 

 

And the sql will retrieve therecord of the patient of message itself, so at last the thread will removeitself and combination to a recorder pair;

         2.2.6

After get the recorder pair thethread will calculate the distance of the two recorder, and the thread use thiscalss like the picture

                   Thiscalss is used like this                 

private HashMap<String,DistanceMetric> distanceMetricCache;

        

         public StringComparisonServiceImpl() {

                   distanceMetricCache = new HashMap<String,DistanceMetric>();

         }

        

         public DistanceMetricType getDistanceMetricType(String name) {

                   return DistanceMetricType.getTypeByName(name);

         }

 

         public DistanceMetricType[] getDistanceMetricTypes() {

                   return DistanceMetricType.getTypes();

         }

 

         // 比較兩個物件,生成所得到的相似分值

         public double score(String metricType, Object value1, Object value2) {

                   DistanceMetric distanceMetric = getDistanceMetric(metricType);

                   return distanceMetric.score(value1, value2);

         }

 

         // 根據傳入的演算法名例項出所進行比較的演算法物件

         private DistanceMetric getDistanceMetric(String metricTypeName) {

                   // If we have the object in the cache, get it from there

                   if (distanceMetricCache.containsKey(metricTypeName)) {

                            return distanceMetricCache.get(metricTypeName);

                   }

                  

                   Object obj = Context.getApplicationContext().getBean(metricTypeName);

                   if (obj == null) {

                            log.error("Unknown distance metric requested: " + metricTypeName);

                            throw new ValidationException("Unknown distance metric requested for string comparision: " + metricTypeName);

                   }

                   DistanceMetric metric = (DistanceMetric) obj;

                   distanceMetricCache.put(metricTypeName, metric);

                   return metric;

         }

         2.2.7

After 2.2.6 the thread get thedistance of recorder pairs and then it will calculate the weight of the pairs ,use the algorithm of this

the distancei is the the score of2.2.6 calculated, and the C is store in the oracle and can be modified byadministrator for every algorithm.

So the weight is got.

2.3

         2.3.1end

                   Afterget the weight , and the weight will be stored into the oracle for more justlike combination the two person or separate the link to two person.

 

That is all , thanks for watching!

相關文章