Browse Source

添加crf依赖

kongwz 5 năm trước cách đây
mục cha
commit
f7a018a539

+ 1 - 1
kernel/src/main/java/com/lantone/qc/kernel/analysis/QCAnalysis.java

@@ -35,7 +35,7 @@ public class QCAnalysis {
         AIAnalyze AIAnalyze = new AIAnalyze(crfServiceClient);
         AIAnalyze.AIprocess(inputInfo);
         for (Map.Entry<String, Map<String, String>> entry : inputInfo.getInputCatalogueMap().entrySet()) {
-            CatalogueUtil.qcCatalogueMap.get(entry.getKey()).execute();
+            CatalogueUtil.qcCatalogueMap.get(entry.getKey()).execute(inputInfo,outputInfo);
         }
         return outputInfo;
     }

+ 4 - 2
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/AIAnalyze.java

@@ -4,6 +4,7 @@ import com.lantone.qc.kernel.client.CRFServiceClient;
 import com.lantone.qc.kernel.structure.ai.model.CrfOut;
 import com.lantone.qc.pub.model.InputInfo;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -16,8 +17,9 @@ public class AIAnalyze {
         this.crfServiceClient = crfService;
     }
     public void AIprocess(InputInfo inputInfo){
-        Map<String, List<CrfOut>> beHospitalized_out = beHospitalizedAI.medrec(inputInfo, crfServiceClient);
-        System.out.printf("");
+//        Map<String, CrfOut> stringCrfOutMap = beHospitalizedAI.medrec_new(inputInfo, crfServiceClient);
+            beHospitalizedAI.medrec(inputInfo, crfServiceClient);
+
 
     }
 

+ 163 - 17
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/BeHospitalizedAI.java

@@ -11,10 +11,15 @@ import com.lantone.qc.pub.Content;
 import com.lantone.qc.pub.model.InputInfo;
 import com.lantone.qc.pub.model.doc.BeHospitalizedDoc;
 import com.lantone.qc.pub.model.entity.Annotation;
+import com.lantone.qc.pub.model.entity.Clinical;
+import com.lantone.qc.pub.model.entity.Diag;
 import com.lantone.qc.pub.model.entity.Lis;
+import com.lantone.qc.pub.model.label.ChiefLabel;
 import com.lantone.qc.pub.model.vo.CRFVo;
 import com.lantone.qc.pub.util.StringUtil;
+import org.apache.commons.lang3.StringUtils;
 
+import java.math.BigInteger;
 import java.util.*;
 
 /**
@@ -37,7 +42,7 @@ public class BeHospitalizedAI {
     public static String entityRelationObject = "entity_relation_object";
     public static String outputs = "outputs";
 
-    public Map<String,List<CrfOut>> medrec(InputInfo inputInfo,CRFServiceClient crfServiceClient){
+    public void medrec(InputInfo inputInfo,CRFServiceClient crfServiceClient){
 
         Map<String,List<CrfOut>> crfOut = new HashMap<>();//主诉-->
         JSONArray crfContent = new JSONArray();
@@ -74,32 +79,107 @@ public class BeHospitalizedAI {
         //获取CRF模型返回数据
         JSONArray data = getAnnotation(crfServiceClient, crfVo).getData();
         JSONObject midData = getOutputs(data);
+        EntityProcessMethod entityProcessMethod = new EntityProcessMethod();
+        putChiefCrfData(midData.getJSONObject(Content.chief),inputInfo,entityProcessMethod);
         //处理主诉
-        putAllCrfData(midData.getJSONObject(Content.chief),crfOut);
-        putAllCrfData(midData.getJSONObject(Content.present), crfOut);
-        putAllCrfData(midData.getJSONObject(Content.special_exam), crfOut);
+//        putAllCrfData(midData.getJSONObject(Content.chief),crfOut);
+//        putAllCrfData(midData.getJSONObject(Content.present), crfOut);
+//        putAllCrfData(midData.getJSONObject(Content.special_exam), crfOut);
+//
+//        //存放CRF模型既往史、家族史返回数据
+//        putAllCrfData(midData.getJSONObject(Content.past), crfOut);
+//        putAllCrfData(midData.getJSONObject(Content.family), crfOut);
+//        //存放CRF模型一般查体(体格检查(一))返回数据
+//        putAllCrfData(midData.getJSONObject(Content.phys_exam), crfOut);
+//        //存放CRF模型个人史、月经史、婚育史返回数据
+//        putAllCrfData(midData.getJSONObject(Content.personal), crfOut);
+//        putAllCrfData(midData.getJSONObject(Content.menses), crfOut);
+//        putAllCrfData(midData.getJSONObject(Content.marriage), crfOut);
+//        //存放CRF模型病历特点、初步诊断、诊断依据返回数据
+//        putAllCrfData(midData.getJSONObject(Content.case_feature), crfOut);
+//        putAllCrfData(midData.getJSONObject(Content.pridiag), crfOut);
+//        putAllCrfData(midData.getJSONObject(Content.diag_basis), crfOut);
+//        return crfOut;
+    }
+    public void putChiefCrfData(JSONObject jsonObject,InputInfo inputInfo,EntityProcessMethod entityProcessMethod){
+        if (jsonObject == null) {
+            return;
+        }
+        JSONObject outputs = jsonObject.getJSONObject(entityRelationObject).getJSONObject(BeHospitalizedAI.outputs);
+        List<Clinical> clinicals = entityProcessMethod.extractClinicalEntity(outputs);
+        List<Diag> diags = entityProcessMethod.extractDiagEntity(outputs);
+        ChiefLabel chiefLabel = inputInfo.getBeHospitalizedDoc().getChiefLabel();
+        chiefLabel.setClinicals(clinicals);
+        chiefLabel.setDiags(diags);
 
-        //存放CRF模型既往史、家族史返回数据
-        putAllCrfData(midData.getJSONObject(Content.past), crfOut);
-        putAllCrfData(midData.getJSONObject(Content.family), crfOut);
-        //存放CRF模型一般查体(体格检查(一))返回数据
-        putAllCrfData(midData.getJSONObject(Content.phys_exam), crfOut);
-        //存放CRF模型个人史、月经史、婚育史返回数据
-        putAllCrfData(midData.getJSONObject(Content.personal), crfOut);
-        putAllCrfData(midData.getJSONObject(Content.menses), crfOut);
-        putAllCrfData(midData.getJSONObject(Content.marriage), crfOut);
-        //存放CRF模型病历特点、初步诊断、诊断依据返回数据
-        putAllCrfData(midData.getJSONObject(Content.case_feature), crfOut);
-        putAllCrfData(midData.getJSONObject(Content.pridiag), crfOut);
-        putAllCrfData(midData.getJSONObject(Content.diag_basis), crfOut);
+    }
+    public Map<String,CrfOut> medrec_new(InputInfo inputInfo,CRFServiceClient crfServiceClient) {
+        Map<String, CrfOut> crfOut = new HashMap<>();//主诉-->
+        JSONArray crfContent = new JSONArray();
+        BeHospitalizedDoc beHospitalizedDoc = inputInfo.getBeHospitalizedDoc();
+        String chief_text = beHospitalizedDoc.getChiefLabel().getText();
+        String Personal_text = beHospitalizedDoc.getPersonalLabel().getText();
+        String family_text = beHospitalizedDoc.getFamilyLabel().getText();
+        String past_text = beHospitalizedDoc.getPastLabel().getText();
+        String present_text = beHospitalizedDoc.getPresentLabel().getText();
+        //月经史
+        String menstrual_text = beHospitalizedDoc.getMenstrualLabel().getText();
+        //婚育史
+        String marital_text = beHospitalizedDoc.getMaritalLabel().getText();
+        //一般体格检查
+        String vital_text = beHospitalizedDoc.getVitalLabel().getText();
+        //专科体格检查
+        String vitalSpecial_text = beHospitalizedDoc.getVitalLabelSpecial().getText();
+        //存放主诉、现病史、专科查体(体格检查(二))
+        putContent(crfContent,medicalTextType.get(3), chief_text,Content.chief);
+        putContent(crfContent,medicalTextType.get(3), present_text,Content.present);
+        putContent(crfContent,medicalTextType.get(3), vitalSpecial_text,Content.special_exam);
+        //存放既往史、家族史
+        putContent(crfContent,medicalTextType.get(3), past_text,Content.past);
+        putContent(crfContent,medicalTextType.get(3), family_text,Content.family);
+        //存放一般查体
+        putContent(crfContent,medicalTextType.get(3), vital_text,Content.phys_exam);
+        //存放个人史、月经史、婚育史
+        putContent(crfContent,medicalTextType.get(3), Personal_text,Content.personal);
+        putContent(crfContent,medicalTextType.get(3), menstrual_text,Content.menses);
+        putContent(crfContent,medicalTextType.get(3), marital_text,Content.marriage);
+        //存储CRF完整所需结构数据
+        CRFVo crfVo = new CRFVo();
+        crfVo.setData(crfContent);
+        //获取CRF模型返回数据
+        JSONArray data = getAnnotation(crfServiceClient, crfVo).getData();
+        JSONObject midData = getOutputs(data);
+        //处理主诉
+        putAllCrfData_new(midData.getJSONObject(Content.chief),crfOut);
+        putAllCrfData_new(midData.getJSONObject(Content.present),crfOut);
         return crfOut;
     }
+    public void putAllCrfData_new(JSONObject jsonObject,Map<String,CrfOut> crfOut){
+        if (jsonObject == null) {
+            return;
+        }
+        JSONObject outputs = jsonObject.getJSONObject(entityRelationObject).getJSONObject(BeHospitalizedAI.outputs);
+        Map<String, Map<String, String>> chiefMap = annsiys_tr(outputs);
+        System.out.println();
 
+    }
+    public void packageData(Map<String, Map<String, String>> chiefMap){
+        if(chiefMap.size()>0){
+            for (Map.Entry<String, Map<String, String>> data:chiefMap.entrySet()) {
+                String key = data.getKey();
+                Map<String, String> value = data.getValue();
+                if(value.size()>0){
+
+                }
+            }
+        }
+    }
     public void putAllCrfData(JSONObject jsonObject,Map<String,List<CrfOut>> crfOut){
         if (jsonObject == null) {
             return;
         }
         JSONObject outputs = jsonObject.getJSONObject(entityRelationObject).getJSONObject(BeHospitalizedAI.outputs);
+        Map<String, Map<String, String>> stringMapMap = annsiys_tr(outputs);
         List<CrfOut> medOut = new ArrayList<>();
         CrfOut outputInfo = new CrfOut();
         add2Output(new EntityProcessSymptom(), outputs, outputInfo);//临床表现
@@ -113,6 +193,72 @@ public class BeHospitalizedAI {
         medOut.add(outputInfo);
         crfOut.put(jsonObject.getString("detail_title"),medOut);
     }
+    public Map<String,Map<String,String>> annsiys_tr(JSONObject outputs){
+        Map<String,Map<String,String>> result_map = new HashMap<>();
+        Map<Integer,List<Integer>> id_map = new HashMap<>();
+        JSONObject annotation = outputs.getJSONObject("annotation");
+        JSONArray entitys = annotation.getJSONArray("T");
+        JSONArray relations = annotation.getJSONArray("R");
+        if(relations.size()>0){
+            for(int i = 0;i<relations.size();i++){
+                if (StringUtils.isEmpty(relations.get(i).toString())) {
+                    continue;
+                }
+                JSONObject jsonObject = relations.getJSONObject(i);
+                if(!jsonObject.isEmpty()){
+                    Integer from_id = jsonObject.getInteger("from");
+                    Integer to_id = jsonObject.getInteger("to");
+                    if(id_map.containsKey(from_id)){
+                        List<Integer> integers = id_map.get(from_id);
+                        integers.add(to_id);
+                        id_map.put(from_id,integers);
+                    }else {
+                        List<Integer> ids = new ArrayList<>();
+                        ids.add(to_id);
+                        id_map.put(from_id,ids);
+                    }
+                }
+            }
+        }
+        if(id_map.size()>0 && entitys.size()>0){
+            for(int i = 0;i<entitys.size();i++){
+                if (StringUtils.isEmpty(entitys.get(i).toString())) {
+                    continue;
+                }
+                JSONObject jsonObject = entitys.getJSONObject(i);
+                if(!jsonObject.isEmpty()){
+                    String name = jsonObject.getString("name");
+                    Integer id = jsonObject.getInteger("id");
+                    String value = jsonObject.getString("value");
+                    if(id_map.keySet().contains(id)){
+                        Map<String,String> rMap = new HashMap<>();
+                        rMap.put("type",name);
+                        List<Integer> ids = id_map.get(id);
+                        if(ids.size()>0){
+                            for (Integer id_n:ids) {
+                                if(entitys.size()>0){
+                                    for(int h = 0;h<entitys.size();h++){
+                                        if (StringUtils.isEmpty(entitys.get(h).toString())) {
+                                            continue;
+                                        }
+                                        JSONObject jsonObject_h = entitys.getJSONObject(h);
+                                        if(!jsonObject_h.isEmpty()){
+                                            Integer id1 = jsonObject_h.getInteger("id");
+                                            if(id_n.equals(id1)){
+                                                rMap.put(jsonObject_h.getString("name"),jsonObject_h.getString("value"));
+                                                result_map.put(value,rMap);
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return result_map;
+    }
     public void add2Output(EntityProcess entityProcess, JSONObject outputs, CrfOut outputInfo){
         entityProcess.extractEntity(outputs, outputInfo);
     }

+ 203 - 0
kernel/src/main/java/com/lantone/qc/kernel/structure/ai/process/EntityProcessMethod.java

@@ -0,0 +1,203 @@
+package com.lantone.qc.kernel.structure.ai.process;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.lantone.qc.kernel.structure.ai.model.CrfOut;
+import com.lantone.qc.kernel.structure.ai.model.EntityEnum;
+import com.lantone.qc.pub.model.entity.*;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class EntityProcessMethod {
+    //获取诊断
+    public List<Diag> extractDiagEntity(JSONObject outputs) {
+        List<Diag> diagnose = new ArrayList<>();
+        Diag diag = null;
+        List<Map<String, String>> diagEntityList = processJson(outputs, EntityEnum.DIEASE.toString());
+        for (Map<String, String> diagEntityMap : diagEntityList) {
+            if (StringUtils.isEmpty(diagEntityMap.get(EntityEnum.DIEASE.toString()))) {
+                continue;
+            }
+            diag = new Diag();
+            for (String key : diagEntityMap.keySet()) {
+                String value = StringUtils.isEmpty(diagEntityMap.get(key)) ? "" : diagEntityMap.get(key);
+                switch (EntityEnum.parseOfValue(key)) {
+                    case DIEASE:
+                        diag.setName(value);
+                        break;
+                    case POSSIBLE:
+                        Possible possible = new Possible();
+                        possible.setName(value);
+                        diag.setPossible(possible);
+                        break;
+                }
+            }
+            diagnose.add(diag);
+        }
+        return diagnose;
+    }
+    //获取临床表现
+    public List<Clinical> extractClinicalEntity(JSONObject outputs) {
+        List<Clinical> clinicals =new ArrayList<>();
+        Clinical clinical;
+        List<Map<String, String>> symptomEntityList = processJson(outputs, EntityEnum.CLINICAL_FEATURE.toString());
+        for (Map<String, String> symptomEntityMap : symptomEntityList) {
+            if (StringUtils.isEmpty(symptomEntityMap.get(EntityEnum.CLINICAL_FEATURE.toString()))) {
+                continue;
+            }
+            clinical = new Clinical();
+            for (String key : symptomEntityMap.keySet()) {
+                String entity = StringUtils.isEmpty(symptomEntityMap.get(key)) ? "" : symptomEntityMap.get(key);
+                switch (EntityEnum.parseOfValue(key)){
+                    case CLINICAL_FEATURE:
+                        clinical.setName(symptomEntityMap.get(key));
+                        break;
+                    case NEGATIVE:
+                        Negative negative = new Negative();
+                        negative.setName(entity);
+                        clinical.setNegative(negative);
+                        break;
+                    case BODY:
+                        BodyPart bodyPart = new BodyPart();
+                        bodyPart.setName(entity);
+                        clinical.setBodyPart(bodyPart);
+                    case TREND:
+                        Trend trend = new Trend();
+                        trend.setName(entity);
+                        clinical.setTrend(trend);
+                    case CAUSE:
+                        Cause cause = new Cause();
+                        cause.setName(entity);
+                        clinical.setCause(cause);
+                    case TIME:
+                        List<PD> timestamp = new ArrayList<>();
+                        PD pd = new PD();
+                        String[] val_unit = new String[2];
+                        if(entity.trim().length()>0){
+                            val_unit = extract_digit(entity);
+                        }
+                        pd.setValue(val_unit[0]);
+                        pd.setUnit(val_unit[1]);
+                        timestamp.add(pd);
+                        clinical.setTimestamp(timestamp);
+                        break;
+                }
+            }
+            clinicals.add(clinical);
+        }
+        return clinicals;
+    }
+    /**
+     * 处理关系抽取输出的json
+     *
+     * @param outputs    关系抽取输出的json
+     * @param entityType 需要处理的实体类别
+     * @return
+     */
+    public List<Map<String, String>> processJson(JSONObject outputs, String entityType) {
+        List<Map<String, String>> connectEntityList = new ArrayList<>();
+        Map<String, String> connectEntity = null;
+        JSONObject annotation = outputs.getJSONObject("annotation");
+        JSONArray entitys = annotation.getJSONArray("T");
+        JSONArray relations = annotation.getJSONArray("R");
+        for (int i = 0; i < entitys.size(); i++) {
+            if (StringUtils.isEmpty(entitys.get(i).toString())) {
+                continue;
+            }
+            JSONObject entity = entitys.getJSONObject(i);
+            if (entityType.equals(entity.getString("name"))) {
+                int id = entity.getIntValue("id");
+                List<Integer> connectEntityIdList = getConnectEntityIdList(id, relations);
+                if (connectEntityIdList.size() == 0) {
+                    connectEntity = new HashMap<>();
+                    connectEntity.put(entity.getString("name"), entity.getString("value"));
+                    connectEntityList.add(connectEntity);
+                } else {
+                    connectEntity = getConnectEntity(connectEntityIdList, entitys);
+                    connectEntity.put(entity.getString("name"), entity.getString("value"));
+                    connectEntityList.add(connectEntity);
+                }
+            }
+        }
+        return connectEntityList;
+    }
+
+    /**
+     * 获取与传入实体有关系实体的id列表(List)
+     *
+     * @param entityId  传入实体的id
+     * @param relations 关系抽取出的关系对
+     * @return connectEntityIdList 有关系实体的id列表(List)
+     */
+    public List<Integer> getConnectEntityIdList(int entityId, JSONArray relations) {
+        List<Integer> connectEntityIdList = new ArrayList<>();
+        for (int i = 0; i < relations.size(); i++) {
+            if (StringUtils.isEmpty(relations.get(i).toString())) {
+                continue;
+            }
+            JSONObject relation = relations.getJSONObject(i);
+            if (relation.getIntValue("from") == entityId) {
+                connectEntityIdList.add(relation.getIntValue("to"));
+            }
+            if (relation.getIntValue("to") == entityId) {
+                connectEntityIdList.add(relation.getIntValue("from"));
+            }
+        }
+        return connectEntityIdList;
+    }
+
+    /**
+     * 获取实体id列表对应的所有实体类型及实体值
+     *
+     * @param connectEntityIdList 实体id列表
+     * @param entitys             关系抽取的实体列表
+     * @return entityRelationPair 实体id列表对应的所有实体类型及实体值
+     */
+    public Map<String, String> getConnectEntity(List<Integer> connectEntityIdList, JSONArray entitys) {
+        Map<String, String> entityRelationPair = new HashMap<>();
+        for (int connectEntityId : connectEntityIdList) {
+            for (int i = 0; i < entitys.size(); i++) {
+                if (StringUtils.isEmpty(entitys.get(i).toString())) {
+                    continue;
+                }
+                JSONObject entity = entitys.getJSONObject(i);
+                if (connectEntityId == entity.getIntValue("id")) {
+                    if (entityRelationPair.containsKey(entity.getString("name"))) {
+                        entityRelationPair.put(entity.getString("name"),
+                                entityRelationPair.get(entity.getString("name")) + "," + entity.getString("value"));
+                    } else {
+                        entityRelationPair.put(entity.getString("name"), entity.getString("value"));
+                    }
+                    break;
+                }
+            }
+        }
+        return entityRelationPair;
+    }
+
+
+    public String[] extract_digit(String value) {
+        String[] res = new String[2];
+        try {
+            String reg_time = "([\\d]+)([\\u4e00-\\u9fa5]+)";
+            Pattern pattern = Pattern.compile(reg_time);
+            Matcher matcher = pattern.matcher(value);
+            if (matcher.find(0)) {
+                res[0] = matcher.group(1);
+                res[1] = matcher.group(2);
+            } else {
+                res[0] = value;
+                res[1] = "";
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+        return res;
+    }
+}

+ 2 - 0
public/src/main/java/com/lantone/qc/pub/model/label/ChiefLabel.java

@@ -1,6 +1,7 @@
 package com.lantone.qc.pub.model.label;
 
 import com.lantone.qc.pub.model.entity.Clinical;
+import com.lantone.qc.pub.model.entity.Diag;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -16,4 +17,5 @@ import java.util.List;
 @Getter
 public class ChiefLabel extends GeneralLabel {
     private List<Clinical> clinicals;
+    private List<Diag> diags;
 }

+ 4 - 0
public/src/main/java/com/lantone/qc/pub/model/label/PacsLabel.java

@@ -1,6 +1,8 @@
 package com.lantone.qc.pub.model.label;
 
 import com.lantone.qc.pub.model.entity.Pacs;
+import lombok.Getter;
+import lombok.Setter;
 
 import java.util.List;
 
@@ -10,6 +12,8 @@ import java.util.List;
  * @Author : 楼辉荣
  * @Date: 2020-03-03 18:50
  */
+@Setter
+@Getter
 public class PacsLabel extends GeneralLabel {
     List<Pacs> pacses;
 }

+ 2 - 4
public/src/main/java/com/lantone/qc/pub/model/label/PresentLabel.java

@@ -1,9 +1,6 @@
 package com.lantone.qc.pub.model.label;
 
-import com.lantone.qc.pub.model.entity.Clinical;
-import com.lantone.qc.pub.model.entity.Lis;
-import com.lantone.qc.pub.model.entity.Pacs;
-import com.lantone.qc.pub.model.entity.Treat;
+import com.lantone.qc.pub.model.entity.*;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -26,4 +23,5 @@ public class PresentLabel extends GeneralLabel {
     private List<Lis> lises;
     //治疗
     private List<Treat> treats;
+    private List<General> generals;
 }