From 7eb2d3874ef3b4c5f32a6911d56eaefae75977eb Mon Sep 17 00:00:00 2001 From: gracsh <97012348+gracsh@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:19:57 -0400 Subject: [PATCH 1/2] Create Chinese --- .../java/org/monarchinitiative/phenopacket2prompt/output/Chinese | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/main/java/org/monarchinitiative/phenopacket2prompt/output/Chinese diff --git a/src/main/java/org/monarchinitiative/phenopacket2prompt/output/Chinese b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/Chinese new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/Chinese @@ -0,0 +1 @@ + From a5199a60e324ac6662959090d4c9660df681e9b6 Mon Sep 17 00:00:00 2001 From: gracsh <97012348+gracsh@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:20:57 -0400 Subject: [PATCH 2/2] Add files via upload --- .../output/impl/ChineseBuildingBlocks.java | 326 ++++++++++++ .../output/impl/ChinesePromptGenerator.java | 0 .../output/impl/PpktIndividualChinese.java | 486 ++++++++++++++++++ .../impl/PpktPhenotypicfeatureChinese.java | 136 +++++ .../output/impl/PpktTextChinese.java | 25 + 5 files changed, 973 insertions(+) create mode 100644 src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/ChineseBuildingBlocks.java create mode 100644 src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/ChinesePromptGenerator.java create mode 100644 src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktIndividualChinese.java create mode 100644 src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktPhenotypicfeatureChinese.java create mode 100644 src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktTextChinese.java diff --git a/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/ChineseBuildingBlocks.java b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/ChineseBuildingBlocks.java new file mode 100644 index 0000000..f353029 --- /dev/null +++ b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/ChineseBuildingBlocks.java @@ -0,0 +1,326 @@ +package org.monarchinitiative.phenopacket2prompt.output.impl.chinese; + +import org.monarchinitiative.phenopacket2prompt.model.Iso8601Age; +import org.monarchinitiative.phenopacket2prompt.output.BuildingBlockGenerator; + +import java.util.ArrayList; +import java.util.List; + +public class ChineseBuildingBlocks implements BuildingBlockGenerator { + @Override + public String days(int d) { + return ""; + } + + @Override + public String months(int m) { + return ""; + } + + @Override + public String years(int y) { + return ""; + } + + @Override + public String yearsOld(int y) { + return String.format("%d岁", y); + } + + @Override + public String monthsOld(int m) { + return String.format("%d个月大", m); + } + + @Override + public String daysOld(int d) { + return String.format("%d天大", d); + } + + @Override + public String monthDayOld(int m, int d) { + List components = new ArrayList<>(); + if (m > 0) { + components.add(String.format("%d个月", m)); + } + if (d > 0) { + components.add(String.format("%d天", d)); + } + if (components.isEmpty()) { + return "自出生起"; + } else if (components.size() == 1) { + return components.get(0); + } else { + return String.format("%s%s大时", components.get(0), components.get(1)); + } + } + + @Override + public String yearsMonthsDaysOld(int y, int m, int d) { + List components = new ArrayList<>(); + if (y > 0) { + components.add(String.format("%d岁", y)); + } + if (m > 0) { + components.add(String.format("%d个月", m)); + } + if (d > 0) { + components.add(String.format("%d天", d)); + } + if (components.isEmpty()) { + return "自出生起"; + } else if (components.size() == 1) { + return components.get(0); + } else if (components.size() == 2) { + return String.format("%s%s大时", components.get(0), components.get(1)); + } else { + // we must have y,m,d + return String.format("%s%s%s大时", components.get(0), components.get(1), components.get(2)); + } + } + + @Override + public String asNewborn() { + return ""; + } + + @Override + public String atTheAgeOf() { + return ""; + } + + @Override + public String she() { + return ""; + } + + @Override + public String he() { + return ""; + } + + @Override + public String theProband() { + return "受试者"; + } + + @Override + public String woman() { + return "女性"; + } + + @Override + public String man() { + return "男性"; + } + + @Override + public String individual() { + return "未知性别成年人"; + } + + @Override + public String theIndividual() { + return ""; + } + + @Override + public String girl() { + return "女孩"; + } + + @Override + public String boy() { + return "男孩"; + } + + @Override + public String child() { + return "儿童"; + } + + @Override + public String adolescentGirl() { + return ""; + } + + @Override + public String adolescentBoy() { + return ""; + } + + @Override + public String adolescentChild() { + return ""; + } + + @Override + public String maleInfant() { + return "男婴"; + } + + @Override + public String femaleInfant() { + return "女婴"; + } + + @Override + public String infant() { + return "婴儿"; + } + + @Override + public String newbornBoy() { + return "男性新生儿"; + } + + @Override + public String newbornGirl() { + return "女性新生儿"; + } + + @Override + public String newborn() { + return "新生儿"; + } + + @Override + public String maleFetus() { + return "男性胎儿"; + } + + @Override + public String femaleFetus() { + return "女性胎儿"; + } + + @Override + public String fetus() { + return "胎儿"; + } + + @Override + public String female() { + return ""; + } + + @Override + public String male() { + return ""; + } + + @Override + public String adult() { + return ""; + } + + @Override + public String probandWasA() { + return "受试者是"; + } + + @Override + public String whoPresented() { + return ""; + } + + @Override + public String presented() { + return ""; + } + + @Override + public String probandNoAgePresented() { + return ""; + } + + @Override + public String probandNoAgePresentedWith() { + return ""; + } + + @Override + public String probandWasAMale() { + return "受试者为一名男性"; + } + + @Override + public String probandWasAFemale() { + return "受试者为一名女性"; + } + + @Override + public String probandWasAnIndividual() { + return "受试者性别未知"; + } + + @Override + public String presentedWith() { + return ""; + } + + @Override + public String with() { + return ""; + } + + @Override + public String inWhomManifestationsWereExcluded() { + return ""; + } + + @Override + public String duringFetal() { + return ""; + } + + @Override + public String asNeonate() { + return ""; + } + + @Override + public String atBirth() { + return ""; + } + + @Override + public String asInfant() { + return ""; + } + + @Override + public String inChildhood() { + return ""; + } + + @Override + public String asAdolescent() { + return ""; + } + + @Override + public String asAdult() { + return ""; + } + + @Override + public String asYoungAdult() { + return ""; + } + + @Override + public String asMiddleAge() { + return ""; + } + + @Override + public String asLateOnset() { + return ""; + } + + @Override + public String fromIso(Iso8601Age ppktAge) { + return ""; + } +} \ No newline at end of file diff --git a/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/ChinesePromptGenerator.java b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/ChinesePromptGenerator.java new file mode 100644 index 0000000..e69de29 diff --git a/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktIndividualChinese.java b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktIndividualChinese.java new file mode 100644 index 0000000..d3429f0 --- /dev/null +++ b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktIndividualChinese.java @@ -0,0 +1,486 @@ +package org.monarchinitiative.phenopacket2prompt.output.impl.chinese; + +import org.monarchinitiative.phenol.base.PhenolRuntimeException; +import org.monarchinitiative.phenopacket2prompt.model.*; +import org.monarchinitiative.phenopacket2prompt.output.BuildingBlockGenerator; +import org.monarchinitiative.phenopacket2prompt.output.PPKtIndividualInfoGenerator; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class PpktIndividualChinese implements PPKtIndividualInfoGenerator { + + private final BuildingBlockGenerator bbGenerator; + /** grammatical sex */ + private enum GrammatikalischesGeschlecht { + MAENNLICH, WEIBLICH, NEUTRUM + }// may not need this + + public PpktIndividualChinese() { + bbGenerator = new ChineseBuildingBlocks(); + } + + @Override + public String getIndividualDescription(PpktIndividual individual) { + if (individual.annotationCount() == 0) { + throw new PhenolRuntimeException("No HPO annotations"); + } + Optional lastExamOpt = individual.getAgeAtLastExamination(); + Optional onsetOpt = individual.getAgeAtOnset(); + PhenopacketSex psex = individual.getSex(); + String individualDescription; + String onsetDescription; + if (lastExamOpt.isPresent()) { + var lastExamAge = lastExamOpt.get(); + if (lastExamAge.ageType().equals(PhenopacketAgeType.ISO8601_AGE_TYPE)) { + Iso8601Age isoAge = (Iso8601Age) lastExamAge; + individualDescription = iso8601individualDescription(psex, isoAge); + } else if (lastExamAge.ageType().equals(PhenopacketAgeType.HPO_ONSET_AGE_TYPE)) { + HpoOnsetAge hpoOnsetTermAge = (HpoOnsetAge) lastExamAge; + individualDescription = hpoOnsetIndividualDescription(psex, hpoOnsetTermAge); + } else { + // should never happen + throw new PhenolRuntimeException("Did not recognize last exam age type " + lastExamAge.ageType()); + } + } else { + individualDescription = switch (psex) { + case FEMALE -> bbGenerator.probandWasAFemale(); + case MALE -> bbGenerator.probandWasAMale(); + default -> bbGenerator.probandWasAnIndividual(); + }; + } + if (onsetOpt.isPresent()) { + var onsetAge = onsetOpt.get(); + if (onsetAge.ageType().equals(PhenopacketAgeType.ISO8601_AGE_TYPE)) { + Iso8601Age isoAge = (Iso8601Age) onsetAge; + onsetDescription = iso8601onsetDescription(isoAge); + } else if (onsetAge.ageType().equals(PhenopacketAgeType.HPO_ONSET_AGE_TYPE)) { + HpoOnsetAge hpoOnsetTermAge = (HpoOnsetAge) onsetAge; + onsetDescription = hpoOnsetDescription(hpoOnsetTermAge); + } else { + // should never happen + throw new PhenolRuntimeException("Did not recognize last exam age type " + onsetAge.ageType()); + } + } else { + onsetDescription = "发病时间未知"; + } + return String.format("%s. %s.", individualDescription, onsetDescription); + } + + private String hpoOnsetDescription(HpoOnsetAge hpoOnsetTermAge) { + return String.format("疾病于患者 %s 发作", + nameOfLifeStage(hpoOnsetTermAge)); + } + + private String nameOfLifeStage(HpoOnsetAge hpoOnsetTermAge) { + if (hpoOnsetTermAge.isFetus()) { + return "胎儿时期"; + } else if (hpoOnsetTermAge.isCongenital()) { + return "出生时"; + } else if (hpoOnsetTermAge.isInfant()) { + return "婴儿时"; + } else if (hpoOnsetTermAge.isChild()) { + return "幼年时"; + } else if (hpoOnsetTermAge.isJuvenile()) { + return "青少年时"; + } else if (hpoOnsetTermAge.isNeonate()) { + return "为新生儿时"; // +bbGenerator.newborn(); + } else if (hpoOnsetTermAge.isYoungAdult()) { + return "青年时" ; + } else if (hpoOnsetTermAge.isMiddleAge()) { + return "中年时" ; + } else if (hpoOnsetTermAge.isLateAdultAge()) { + return "晚年时" ; + } else if (hpoOnsetTermAge.isAdult()) { + // d.h. nicht weiter spezifiziert + return "成年后" ; + } else { + throw new PhenolRuntimeException("Could not identify German life stage name for HpoOnsetAge " + hpoOnsetTermAge.toString()); + } + } + + private String iso8601onsetDescription(Iso8601Age isoAge) { + return String.format("发病时间为 %s ", + bbGenerator.yearsMonthsDaysOld(isoAge.getYears(), isoAge.getMonths(), isoAge.getDays())); + } + + + + + + + + public String ageAndSexAtLastExamination(PpktIndividual individual) { + PhenopacketSex psex = individual.getSex(); + Optional ageOpt = individual.getAgeAtLastExamination(); + if (ageOpt.isEmpty()) { + ageOpt = individual.getAgeAtOnset(); + } + String sex; + switch (psex) { + case FEMALE -> sex = bbGenerator.woman(); + case MALE -> sex = bbGenerator.man(); + default -> sex = bbGenerator.adult(); + } + + if (ageOpt.isEmpty()) { + return sex; + } + PhenopacketAge age = ageOpt.get(); + if (age.ageType().equals(PhenopacketAgeType.ISO8601_AGE_TYPE)) { + Iso8601Age isoage = (Iso8601Age) age; + int y = isoage.getYears(); + int m = isoage.getMonths(); + int d = isoage.getDays(); + if (psex.equals(PhenopacketSex.FEMALE)) { + if (y > 17) { + return String.format("%d 岁患者", y); + } else if (y > 9) { + return String.format("%d 岁女孩", y); + } else if (y > 0) { + return String.format("%d 岁女童", y); + } else if (m>0) { + return String.format("%d 月大的女婴", m); + } else { + return String.format("%d 天大的女婴", d); + } + } + } else { + // age is an HPO onset term, we do not have an exact date + } + if (age.isChild()) { + return switch (psex) { + case FEMALE -> bbGenerator.girl(); + case MALE -> bbGenerator.boy(); + default -> bbGenerator.child(); + }; + } else if (age.isCongenital()) { + return switch (psex) { + case FEMALE -> bbGenerator.newbornGirl(); + case MALE -> bbGenerator.newbornBoy(); + default -> bbGenerator.newborn(); + }; + } else if (age.isFetus()) { + return switch (psex) { + case FEMALE -> bbGenerator.femaleFetus(); + case MALE -> bbGenerator.maleFetus(); + default -> bbGenerator.fetus(); + }; + } else if (age.isInfant()) { + return switch (psex) { + case FEMALE -> bbGenerator.femaleInfant(); + case MALE -> bbGenerator.maleInfant(); + default -> bbGenerator.infant(); + }; + } else { + return switch (psex) { + // TODO -- MORE GRANULARITY + case FEMALE -> bbGenerator.woman(); + case MALE -> bbGenerator.man(); + default -> bbGenerator.adult(); + }; + } + } + + + private String imAlterVonIsoAgeExact(PhenopacketAge ppktAge) { + Iso8601Age iso8601Age = (Iso8601Age) ppktAge; + int y = iso8601Age.getYears(); + int m = iso8601Age.getMonths(); + int d = iso8601Age.getDays(); + + if (y > 10) { + return String.format("%d岁时", y); + } else if (y > 0) { + if (m > 0) { + return String.format("%d岁%d个月时", y, + m); + } else { + return String.format("%d岁时", y); + } + } + if (m>0) { + return String.format("%d个月%d天大时", m, + d); + } else { + return String.format("%d天大时", d); + } + } + + + private String iso8601individualDescription(PhenopacketSex psex, Iso8601Age iso8601Age) { + int y = iso8601Age.getYears(); + int m = iso8601Age.getMonths(); + int d = iso8601Age.getDays(); + // if older + if (y > 17) { + return switch (psex) { + case FEMALE -> String.format("受试者是一名 %s 岁的女性", + dAlter(iso8601Age, GrammatikalischesGeschlecht.WEIBLICH)); + case MALE -> String.format("受试者是一名 %s 岁的男性", + dAlter(iso8601Age, GrammatikalischesGeschlecht.MAENNLICH)); + default -> String.format("受试者是一名%s %s", + dAlter(iso8601Age, GrammatikalischesGeschlecht.NEUTRUM), + bbGenerator.individual()); + }; + } else if (y > 9) { + return switch (psex) { + case FEMALE -> String.format("%s %s %s", bbGenerator.probandWasA(), + dAlter(iso8601Age, GrammatikalischesGeschlecht.WEIBLICH), + bbGenerator.adolescentGirl()); + case MALE -> String.format("%s %s %s", bbGenerator.probandWasA(), + dAlter(iso8601Age, GrammatikalischesGeschlecht.MAENNLICH), + bbGenerator.adolescentBoy()); + default -> String.format("%s %s %s", bbGenerator.probandWasA(), + dAlter(iso8601Age, GrammatikalischesGeschlecht.NEUTRUM), bbGenerator.adolescentChild()); + }; + } else if (y > 0) { + return switch (psex) { + case FEMALE -> String.format("%s %s %s", bbGenerator.probandWasA(), + dAlter(iso8601Age, GrammatikalischesGeschlecht.NEUTRUM), // "das Mädchen" + bbGenerator.girl()); + case MALE -> String.format("%s ein %s %s", bbGenerator.probandWasA(), + dAlter(iso8601Age, GrammatikalischesGeschlecht.MAENNLICH), + bbGenerator.boy()); + default -> String.format("%s %s %s", bbGenerator.probandWasA(), + dAlter(iso8601Age, GrammatikalischesGeschlecht.NEUTRUM), // Das Individuum + bbGenerator.child()); + }; + } else if (m > 0 || d > 0) { + return switch (psex) { + case FEMALE -> String.format("%s ein %s %s", bbGenerator.probandWasA(), + dAlter(iso8601Age, GrammatikalischesGeschlecht.MAENNLICH), // "der weibliche Säungling", + bbGenerator.femaleInfant()); + case MALE -> String.format("%s ein %s %s", bbGenerator.probandWasA(), + dAlter(iso8601Age, GrammatikalischesGeschlecht.MAENNLICH), + bbGenerator.maleInfant()); + default -> String.format("%s ein %s %s", bbGenerator.probandWasA(), + dAlter(iso8601Age, GrammatikalischesGeschlecht.MAENNLICH), // "der Säugling + bbGenerator.infant()); + }; + } else { + return switch (psex) { + case FEMALE -> String.format("Die Probandin war ein %s", bbGenerator.probandWasA(), bbGenerator.newbornGirl()); // das + case MALE -> String.format("Der Proband war ein %s", bbGenerator.probandWasA(), bbGenerator.newbornBoy()); + default -> String.format("Der Proband war ein Neugeborenes ohne angegebenes Geschlecht"); + }; + } + } + + /** + * @param iso8601Age + * @return zB. "4 Jahre und 2 Monate alter" "3 Monate und 1 Tag altes" + */ + private String dAlter(Iso8601Age iso8601Age, GrammatikalischesGeschlecht geschlecht) { + int y = iso8601Age.getYears(); + int m = iso8601Age.getMonths(); + int d = iso8601Age.getDays(); + List components = new ArrayList<>(); + if (y > 0) { + components.add(String.format("%d岁", y)); + } + if (m > 0) { + components.add(String.format("%d个月", m)); + } + if (d > 0) { + components.add(String.format("%d天", d)); + } + String ymd; + if (components.isEmpty()) { + ymd = ""; + } else if (components.size() == 1) { + ymd = components.get(0); + } else if (components.size() == 2) { + ymd = String.format("%s%s", components.get(0), components.get(1)); + } else { + ymd = String.format("%s%s%s", components.get(0), components.get(1), components.get(2)); + } + + /* + return switch (geschlecht) { //may not need this switch function + case MAENNLICH -> String.format("%s alter", ymd); + case WEIBLICH -> String.format("%s alte", ymd); + case NEUTRUM -> String.format("%s altes", ymd); + }; + */ + return String.format("%s时",ymd) + } + + + private String iso8601ToYearMonth(Iso8601Age iso8601Age, PhenopacketSex psex) { + int y = iso8601Age.getYears(); + int m = iso8601Age.getMonths(); + int d = iso8601Age.getDays(); + if (psex.equals(PhenopacketSex.MALE)) { + if (iso8601Age.getMonths() == 0) { + return String.format("%d岁男孩", y); + } else { + return String.format("%d岁%d个月大的男孩", y,m); + } + } else if (psex.equals(PhenopacketSex.FEMALE)) { + if (iso8601Age.getMonths() == 0) { + return String.format("%d岁女孩", y); + } else { + return String.format("%d岁%d个月大女孩", y, m); + } + } + if (iso8601Age.getMonths() == 0) { + return String.format("%d岁儿童", y); + } else { + return String.format("%d岁%d个月大儿童", y, m); } + } + + private String monthString(int m) { + return m>1 ? "个月": "个月"; // maynot need this + } + + private String dayString(int d) { + return d>1 ? "天": "天"; // maynot need this + } + + private String iso8601ToMonthDay(Iso8601Age iso8601Age) { + int m = iso8601Age.getMonths(); + int d = iso8601Age.getDays(); + if (m == 0) { + return String.format("%d天大", d); + } else if (d>0){ + return String.format("%d个月%d天大", m, d); + } else { + return String.format("%d个月大", m); + } + } + + /** + * Create a phrase such as "at the age of 7 years, 4 months, and 2 days" + * Leave out the months and days if they are zero. + * @param isoAge + * @return + */ + private String iso8601AtAgeOf(Iso8601Age isoAge) { + List components = new ArrayList<>(); + + if (isoAge.getYears()>=1) { + components.add(String.format("%d岁", isoAge.getYears())); + //} else if (isoAge.getYears() == 1) { //maynot need to seperate the case ==1 + // components.add("einem Jahr"); + } + if (isoAge.getMonths() >= 1) { + components.add(String.format("%d个月", isoAge.getMonths())); + //} else if (isoAge.getMonths() == 1) { + // components.add("einem Monat"); + } + if (isoAge.getDays()>=1) { + components.add(String.format("%d天", isoAge.getDays())); + //} else if (isoAge.getDays()==1) { + // components.add("einem Tag"); + } + if (components.isEmpty()) { + return "出生时"; + } else if (components.size() == 1) { + return components.getFirst()+"大"; + } else if (components.size() == 2) { + return components.get(0) + components.get(1)+"大"; + } else { + return components.get(0)+ components.get(1) + + components.get(2)+"大"; + } + } +/* + private String onsetTermAtAgeOf(HpoOnsetAge hpoOnsetTermAge) { + if (hpoOnsetTermAge.isFetus()) { + return "in der Fetalperiode"; + } else if (hpoOnsetTermAge.isCongenital()) { + return "bei der Geburt"; + } else if (hpoOnsetTermAge.isInfant()) { + return "im Säuglingsalter"; + } else if (hpoOnsetTermAge.isChild()) { + return "in der Kindheit"; + } else if (hpoOnsetTermAge.isJuvenile()) { + return "als Jugendlich adolescente"; + } else { + return "im Erwachsenenalter"; + } + } +*/ + + + private String hpoOnsetIndividualDescription(PhenopacketSex psex, HpoOnsetAge hpoOnsetTermAge) { + if (hpoOnsetTermAge.isFetus()) { + return switch (psex) { + case FEMALE -> String.format("%s %s", bbGenerator.probandWasAFemale(), bbGenerator.femaleFetus()); + case MALE -> String.format("%s %s", bbGenerator.probandWasAMale(), bbGenerator.maleFetus()); + default -> String.format("%s %s", bbGenerator.probandWasA(), bbGenerator.fetus()); + }; + } else if (hpoOnsetTermAge.isCongenital()) { + return switch (psex) { + case FEMALE -> "受试者为女性新生儿"; + case MALE -> "受试者为男性新生儿"; + default -> "受试者为新生儿,性别不详"; + }; + } else if (hpoOnsetTermAge.isInfant()) { + return switch (psex) { + case FEMALE -> "受试者为一名女婴"; + case MALE -> "受试者为一名男婴"; + default -> "受试者为婴幼儿,性别不详"; + }; + } else if (hpoOnsetTermAge.isChild()) { + return switch (psex) { + case FEMALE -> "受试者为一名女童"; + case MALE -> "受试者为一名男童"; + default -> "受试者为儿童,性别不详"; + }; + } else if (hpoOnsetTermAge.isJuvenile()) { + return switch (psex) { + case FEMALE -> "受试者为女性青少年"; + case MALE -> "受试者为男性青少年"; + default -> "受试者为青少年,性别不详"; + }; + } else if (hpoOnsetTermAge.isAdult()) { + return switch (psex) { + case FEMALE -> "受试者为成年女性"; + case MALE -> "受试者为成年男性"; + default -> "受试者已成年,性别不详"; + + }; + } else { + throw new PhenolRuntimeException("Could not find HPO onset type " + hpoOnsetTermAge.toString()); + } + } + + + @Override + public String heSheIndividual(PhenopacketSex psex) { + return switch (psex) { + case FEMALE -> "她"; + case MALE -> "他"; + default -> "患者"; + }; + } + + @Override + public String atAgeForVignette(PhenopacketAge ppktAge) { + if (ppktAge.ageType().equals(PhenopacketAgeType.ISO8601_AGE_TYPE)) { + return imAlterVonIsoAgeExact(ppktAge); + } else if (ppktAge.ageType().equals(PhenopacketAgeType.HPO_ONSET_AGE_TYPE)) { + String label = ppktAge.age(); // something like "Infantile onset" + return switch (label) { + case "Infantile onset" -> "婴幼儿时"; + case "Childhood onset" -> "童年时"; + case "Neonatal onset" -> "在新生儿时期"; + case "Congenital onset" -> "出生时"; + case "Adult onset" -> "成年后"; + case "Juvenile onset" -> "青少年时期"; + default-> { + throw new PhenolRuntimeException("No Chinese translation for " + label); + } + }; + } else { + return ""; // should never get here + } + } + + + + +} \ No newline at end of file diff --git a/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktPhenotypicfeatureChinese.java b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktPhenotypicfeatureChinese.java new file mode 100644 index 0000000..9fda9ef --- /dev/null +++ b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktPhenotypicfeatureChinese.java @@ -0,0 +1,136 @@ +package org.monarchinitiative.phenopacket2prompt.output.impl.chinese; + +import org.monarchinitiative.phenol.base.PhenolRuntimeException; +import org.monarchinitiative.phenopacket2prompt.international.HpInternational; +import org.monarchinitiative.phenopacket2prompt.model.OntologyTerm; +import org.monarchinitiative.phenopacket2prompt.output.PpktPhenotypicFeatureGenerator; + +import java.util.*; +import java.util.stream.Collectors; + +public class PpktPhenotypicfeatureChinese implements PpktPhenotypicFeatureGenerator { + + private final HpInternational chinese; + private Set missingTranslations; + + + public PpktPhenotypicfeatureChinese(HpInternational international) { + german = international; + missingTranslations = new HashSet<>(); + } + + + private List getTranslations(List ontologyTerms) { + List labels = new ArrayList<>(); + for (var term: ontologyTerms) { + Optional opt = german.getLabel(term.getTid()); + if (opt.isPresent()) { + labels.add(opt.get()); + } else { + String missing = String.format(" %s (%s)", term.getLabel(), term.getTid().getValue()); + missingTranslations.add(missing); + } + } + return labels; + } + + + + private String getCommaList(List items) { + if (items.isEmpty()) { + return ""; // this will be filtered out later + } + if (items.size() == 1) { + return items.getFirst(); + } + if (items.size() == 2) { + // no comma if we just have two items. + // one item will work with the below code + return String.join("和", items); + } + // if we have more than two, join all but the very last item with a comma + String penultimate = items.stream() + .limit(items.size() - 1) + .collect(Collectors.joining(",")); + String ultimate = items.get(items.size() - 1); + return penultimate + "和" + ultimate; + } + + @Override + public String formatFeatures(List ontologyTerms) { + List observedTerms = getObservedFeatures(ontologyTerms); + List excludedTerms = getExcludedFeatures(ontologyTerms); + List observedLabels = getTranslations(observedTerms); + List excludedLabels = getTranslations(excludedTerms); + if (observedLabels.isEmpty() && excludedLabels.isEmpty()) { + return "无异常"; // should never happen, actually! + } else if (excludedLabels.isEmpty()) { + return getCommaList(observedLabels) + ". "; + } else if (observedLabels.isEmpty()) { + if (excludedLabels.size() > 1) { + return String.format("%s被排除在外。", getCommaList(excludedLabels)); + } else { + return String.format("%s被排除在外。",excludedLabels.getFirst()); + } + } else { + String exclusion = String.format("%s被排除在外。", getCommaList(excludedLabels)); + return getCommaList(observedLabels) + "。 " + exclusion; // check this + } + } + + public Set getMissingTranslations() { + return missingTranslations; + } + + + @Override + public String featuresAtEncounter(String personString, String ageString, List ontologyTerms) { + List observed = getObservedFeatures(ontologyTerms); + List excluded = getExcludedFeatures(ontologyTerms); + List observedGerman = getTranslations(observed); + List excludedGerman = getTranslations(excluded); + var observedStr = getCommaList(observedGerman); + var excludedStr = getCommaList(excludedGerman); + if (!observed.isEmpty() && ! excluded.isEmpty()) { + return String.format("%s %s出现以下症状: %s. 以下症状被排除: %s.", + ageString, + personString, + observedStr, + excludedStr); + } else if (!observed.isEmpty()) { + return String.format("%s %s 出现以下症状: %s.", ageString, personString, observedStr); + } else if (!excluded.isEmpty()) { + return String.format("%s 排除以下症状: %s.", + ageString, excludedStr); + } else { + throw new PhenolRuntimeException("No features found for time point " + ageString); // should never happen + } + } + + @Override + public String featuresAtOnset(String personString, List ontologyTerms) { + List observed = getObservedFeatures(ontologyTerms); + List excluded = getExcludedFeatures(ontologyTerms); + List observedGerman = getTranslations(observed); + List excludedGerman = getTranslations(excluded); + var observedStr = getCommaList(observedGerman); + var excludedStr = getCommaList(excludedGerman); + + if (!observed.isEmpty() && ! excluded.isEmpty()) { + return String.format("%s 出现了以下症状: %s. 以下症状被排除: %s.", + personString, + observedStr, + excludedStr); + } else if (!observed.isEmpty()) { + return String.format("%s 出现以下症状: %s.", personString, observedStr); + } else if (!excluded.isEmpty()) { + return String.format("疾病发作时,排除以下症状: %s.", + excludedStr); + } else { + return "疾病发作时无明确描述症状."; + } + } + + + +} \ No newline at end of file diff --git a/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktTextChinese.java b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktTextChinese.java new file mode 100644 index 0000000..5b66691 --- /dev/null +++ b/src/main/java/org/monarchinitiative/phenopacket2prompt/output/impl/PpktTextChinese.java @@ -0,0 +1,25 @@ +package org.monarchinitiative.phenopacket2prompt.output.impl.chinese; + +import org.monarchinitiative.phenopacket2prompt.output.PhenopacketTextGenerator; + +public class PpktTextChinese implements PhenopacketTextGenerator { + + @Override + public String GPT_PROMPT_HEADER() { + return """ +我正在对一份临床病例进行测试,以将您的诊断与人类专家的诊断进行比较。我将向您提供一个医疗案例中的部分信息,而您将作为一个提供诊断的人工智能语言模型“gpt-4医生”对案例进行诊断。以下是操作说明: +首先,每个案例有仅有一个人类已知的明确疾病。其次,大部分的诊断结果都有相对应的基因测试佐证。在极少数情况下,当相对应的基因测试不存在时,我们则使用已经过验证的临床标准或者专家意见进行诊断。 + +在您阅读完病例后,请您做出诊断,并将可能存在的疾病依据概率大小进行排序(最有可能的疾病排在最前)并标明疾病名称。例如,如果第一个疾病是鳃面综合征,第二个疾病是囊性纤维化,请用英语提供以下内容: + +1. Branchiooculofacial syndrome +2. Cystic fibrosis + +请在您的回答中包含尽可能多的有关疾病,并使用英文进行作答。在回答中,您不需要提供诊断的依据或理由,仅需列出疾病名称即可。 + +案例如下: + +"""; + } + +} \ No newline at end of file