Skip to content

Commit

Permalink
feat(pharmcat): add FDA PGx association recommendations
Browse files Browse the repository at this point in the history
- add FDA PGx Assocation recommendation data
- add new DataSourceType class to group recommendation datas
- rename recommendation data files to accommodate two FDA data types
  • Loading branch information
whaleyr committed Mar 11, 2024
1 parent 999d579 commit f2e2be1
Show file tree
Hide file tree
Showing 339 changed files with 15,368 additions and 463 deletions.
7 changes: 3 additions & 4 deletions src/main/java/org/pharmgkb/pharmcat/BaseConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.pharmgkb.common.util.CliHelper;
import org.pharmgkb.pharmcat.reporter.model.DataSource;
import org.pharmgkb.pharmcat.reporter.model.DataSourceType;


/**
Expand All @@ -40,7 +40,7 @@ public class BaseConfig {
boolean runReporter = true;
String reporterTitle;
boolean reporterCompact = true;
List<DataSource> reporterSources;
List<DataSourceType> reporterSources;
boolean reporterJson;
boolean reporterHtml = true;
Path outputDir;
Expand Down Expand Up @@ -93,7 +93,6 @@ public class BaseConfig {
topCandidateOnly = !cliHelper.hasOption("ma");

if (cliHelper.hasOption("research")) {
//noinspection UnstableApiUsage
List<String> types = sf_commaSplitter.splitToStream(Objects.requireNonNull(cliHelper.getValue("research")))
.map(String::toLowerCase)
.collect(Collectors.toList());
Expand Down Expand Up @@ -134,7 +133,7 @@ public class BaseConfig {
reporterSources = new ArrayList<>();
for (String src : sf_commaSplitter.splitToList(Objects.requireNonNull(cliHelper.getValue("rs")))) {
try {
reporterSources.add(DataSource.valueOf(src.toUpperCase()));
reporterSources.add(DataSourceType.valueOf(src));
} catch (IllegalArgumentException ex) {
throw new ReportableException("Unknown source: " + src);
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/pharmgkb/pharmcat/Pipeline.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import org.pharmgkb.pharmcat.reporter.ReportContext;
import org.pharmgkb.pharmcat.reporter.format.HtmlFormat;
import org.pharmgkb.pharmcat.reporter.format.JsonFormat;
import org.pharmgkb.pharmcat.reporter.model.DataSource;
import org.pharmgkb.pharmcat.reporter.model.DataSourceType;


/**
Expand Down Expand Up @@ -64,7 +64,7 @@ public enum Mode {
private Path m_reporterInputFile;
private String m_reporterTitle;
private boolean m_reporterCompact;
private List<DataSource> m_reporterSources;
private List<DataSourceType> m_reporterSources;
private Path m_reporterJsonFile;
private Path m_reporterHtmlFile;
private ReportContext m_reportContext;
Expand All @@ -83,7 +83,7 @@ public Pipeline(Env env,
boolean topCandidateOnly, boolean callCyp2d6, boolean findCombinations, boolean matcherHtml,
boolean runPhenotyper, @Nullable Path phenotyperInputFile, @Nullable Path phenotyperOutsideCallsFile,
boolean runReporter, @Nullable Path reporterInputFile, @Nullable String reporterTitle,
@Nullable List<DataSource> reporterSources, boolean reporterCompact, boolean reporterJson, boolean reporterHtml,
@Nullable List<DataSourceType> reporterSources, boolean reporterCompact, boolean reporterJson, boolean reporterHtml,
@Nullable Path outputDir, @Nullable String baseFilename, boolean deleteIntermediateFiles,
Mode mode, @Nullable String displayCount, boolean verbose) throws ReportableException {
m_env = env;
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/org/pharmgkb/pharmcat/reporter/MessageHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.pharmgkb.common.util.PathUtils;
import org.pharmgkb.pharmcat.reporter.model.DataSource;
import org.pharmgkb.pharmcat.reporter.model.DataSourceType;
import org.pharmgkb.pharmcat.reporter.model.MatchLogic;
import org.pharmgkb.pharmcat.reporter.model.MessageAnnotation;
import org.pharmgkb.pharmcat.reporter.model.VariantReport;
Expand Down Expand Up @@ -153,33 +154,33 @@ else if (!StringUtils.isBlank(match.getVariant()) &&
* @param drugReport a {@link DrugReport} to add message annotations to
* @param reportContext the report context to pull related information from
*/
public void addMatchingMessagesTo(DrugReport drugReport, ReportContext reportContext, DataSource source) {
public void addMatchingMessagesTo(DrugReport drugReport, ReportContext reportContext, DataSourceType source) {
Collection<MessageAnnotation> allMessages = m_drugMap.get(drugReport.getName()).stream()
.filter((ma) -> allowedForSource(ma, source))
.filter((ma) -> allowedForSource(ma, source.getDataSource()))
.toList();
if (allMessages.size() == 0) {
if (allMessages.isEmpty()) {
return;
}
List<MessageAnnotation> reportAsGenotype = new ArrayList<>();
for (MessageAnnotation messageAnnotation : allMessages) {
if (messageAnnotation.getExceptionType().equals(MessageAnnotation.TYPE_REPORT_AS_GENOTYPE)) {
reportAsGenotype.add(messageAnnotation);
} else {
if (matchDrugReport(messageAnnotation, reportContext, source)) {
if (matchDrugReport(messageAnnotation, reportContext, source.getDataSource())) {
drugReport.addMessage(messageAnnotation);
}
}
}

if (reportAsGenotype.size() > 0) {
if (!reportAsGenotype.isEmpty()) {
for (MessageAnnotation msgAnn : reportAsGenotype) {
String geneSymbol = msgAnn.getMatches().getGene();
String genotype = null;
for (GuidelineReport guidelineReport : drugReport.getGuidelines()) {
if (geneSymbol == null || guidelineReport.getGenes().contains(geneSymbol)) {
for (AnnotationReport annotationReport : guidelineReport.getAnnotations()) {
if (genotype == null) {
genotype = computeGenotype(msgAnn, reportContext, source);
genotype = computeGenotype(msgAnn, reportContext, source.getDataSource());
}
annotationReport.addHighlightedVariant(genotype);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.google.common.collect.TreeMultimap;
import org.pharmgkb.common.util.PathUtils;
import org.pharmgkb.pharmcat.reporter.model.DataSource;
import org.pharmgkb.pharmcat.reporter.model.DataSourceType;
import org.pharmgkb.pharmcat.reporter.model.pgkb.AccessionObject;
import org.pharmgkb.pharmcat.reporter.model.pgkb.GuidelinePackage;
import org.pharmgkb.pharmcat.util.DataSerializer;
Expand All @@ -41,7 +42,7 @@ public PgkbGuidelineCollection(Path dir) throws IOException {
stream.filter(f -> f.getFileName().toString().endsWith(".json"))
.forEach(annotationFiles::add);
}}
if (annotationFiles.size() == 0) {
if (annotationFiles.isEmpty()) {
throw new IOException("Cannot find annotations");
}

Expand All @@ -60,9 +61,9 @@ public List<GuidelinePackage> getGuidelinePackages() {
return f_guidelinePackages;
}

public List<GuidelinePackage> findGuidelinePackages(String chemicalName, DataSource source) {
public List<GuidelinePackage> findGuidelinePackages(String chemicalName, DataSourceType source) {
return f_guidelineMap.get(chemicalName).stream()
.filter(p -> p.getGuideline().getSource().equalsIgnoreCase(source.getPharmgkbName()))
.filter(p -> p.isDataSourceType(source))
.collect(Collectors.toList());
}

Expand Down
25 changes: 12 additions & 13 deletions src/main/java/org/pharmgkb/pharmcat/reporter/ReportContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import com.google.common.collect.ImmutableList;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.pharmgkb.pharmcat.Env;
import org.pharmgkb.pharmcat.reporter.model.DataSource;
import org.pharmgkb.pharmcat.reporter.model.DataSourceType;
import org.pharmgkb.pharmcat.reporter.model.MessageAnnotation;
import org.pharmgkb.pharmcat.reporter.model.ObjectType;
import org.pharmgkb.pharmcat.reporter.model.pgkb.GuidelinePackage;
import org.pharmgkb.pharmcat.reporter.model.result.DrugReport;
import org.pharmgkb.pharmcat.reporter.model.result.GeneReport;
Expand All @@ -30,8 +31,6 @@
* @author Ryan Whaley
*/
public class ReportContext {
private static final List<DataSource> DRUG_REPORT_SOURCES = ImmutableList.of(DataSource.CPIC, DataSource.DPWG, DataSource.FDA);

@Expose
@SerializedName("title")
private final String f_title;
Expand All @@ -52,7 +51,7 @@ public class ReportContext {
private final SortedMap<DataSource, SortedMap<String, GeneReport>> m_geneReports;
@Expose
@SerializedName("drugs")
private final SortedMap<DataSource, SortedMap<String, DrugReport>> m_drugReports = new TreeMap<>();
private final SortedMap<DataSourceType, SortedMap<String, DrugReport>> m_drugReports = new TreeMap<>();
@Expose
@SerializedName("messages")
private final List<MessageAnnotation> f_messages = new ArrayList<>();
Expand All @@ -70,12 +69,12 @@ public ReportContext(Env env, SortedMap<DataSource, SortedMap<String, GeneReport
m_cpicVersion = validateVersions(env.getDrugs(), DataSource.CPIC);
m_dpwgVersion = validateVersions(env.getDrugs(), DataSource.DPWG);

for (DataSource dataSource : DRUG_REPORT_SOURCES) {
Map<String, DrugReport> drugReports = m_drugReports.computeIfAbsent(dataSource, (s) -> new TreeMap<>());
for (DataSourceType dataSourceType : DataSourceType.listValidDataSourceTypes()) {
Map<String, DrugReport> drugReports = m_drugReports.computeIfAbsent(dataSourceType, (s) -> new TreeMap<>());
// go through all drugs, we iterate this way because one guideline may have multiple chemicals/drugs
for (String drugName : env.getDrugs().getGuidelineMap().keys()) {
List<GuidelinePackage> guidelinePackages = env.getDrugs().findGuidelinePackages(drugName, dataSource);
if (guidelinePackages != null && guidelinePackages.size() > 0) {
List<GuidelinePackage> guidelinePackages = env.getDrugs().findGuidelinePackages(drugName, dataSourceType);
if (guidelinePackages != null && !guidelinePackages.isEmpty()) {
DrugReport newDrugReport = new DrugReport(drugName, guidelinePackages, this);
drugReports.put(drugName.toLowerCase(), newDrugReport);
}
Expand All @@ -89,13 +88,13 @@ public ReportContext(Env env, SortedMap<DataSource, SortedMap<String, GeneReport
.flatMap((m) -> m.values().stream())
.forEach(messageHelper::addMatchingMessagesTo);
// to drug reports
for (DataSource source : m_drugReports.keySet()) {
for (DataSourceType source : m_drugReports.keySet()) {
for (DrugReport drugReport : m_drugReports.get(source).values()) {
messageHelper.addMatchingMessagesTo(drugReport, this, source);

// add a message for any gene that has missing data
drugReport.getRelatedGeneSymbols().stream()
.map((s) -> getGeneReport(source, s))
.map((s) -> getGeneReport(source.getDataSource(), s))
.filter((gr) -> gr != null && !gr.isOutsideCall() && gr.isMissingVariants() && !gr.isNoData())
.forEach((gr) -> drugReport.addMessage(new MessageAnnotation(MessageAnnotation.TYPE_NOTE,
"missing-variants",
Expand Down Expand Up @@ -150,7 +149,7 @@ private String validateVersions(PgkbGuidelineCollection guidelineCollection, Dat
*
* @return a map of {@link DrugReport} objects
*/
public Map<DataSource, SortedMap<String, DrugReport>> getDrugReports() {
public Map<DataSourceType, SortedMap<String, DrugReport>> getDrugReports() {
return m_drugReports;
}

Expand All @@ -168,8 +167,8 @@ public List<DrugReport> getDrugReports(String drug) {
.toList();
}

public @Nullable DrugReport getDrugReport(DataSource source, String drug) {
return m_drugReports.get(source).get(drug);
public @Nullable DrugReport getDrugReport(DataSource source, ObjectType type, String drug) {
return m_drugReports.get(new DataSourceType(source, type)).get(drug);
}

public List<GeneReport> getGeneReports(String gene) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.stream.Collectors;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.helper.StringHelpers;
import com.github.jknack.handlebars.io.ClassPathTemplateLoader;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
Expand All @@ -30,6 +31,7 @@
import org.pharmgkb.pharmcat.reporter.format.html.Recommendation;
import org.pharmgkb.pharmcat.reporter.handlebars.ReportHelpers;
import org.pharmgkb.pharmcat.reporter.model.DataSource;
import org.pharmgkb.pharmcat.reporter.model.DataSourceType;
import org.pharmgkb.pharmcat.reporter.model.MessageAnnotation;
import org.pharmgkb.pharmcat.reporter.model.result.CallSource;
import org.pharmgkb.pharmcat.reporter.model.result.DrugLink;
Expand All @@ -48,7 +50,8 @@ public class HtmlFormat extends AbstractFormat {
private static final String sf_templatePrefix = "/org/pharmgkb/pharmcat/reporter";
private static final String sf_handlebarTemplateName = "report";
private static final boolean sf_compact_drugs = false;
private List<DataSource> m_sources = Lists.newArrayList(DataSource.CPIC, DataSource.DPWG, DataSource.FDA);
private Set<DataSource> m_geneSources = ImmutableSet.of(DataSource.CPIC, DataSource.DPWG);
private List<DataSourceType> m_sources = DataSourceType.listValidDataSourceTypes();
private boolean m_compact;
private final boolean f_testMode;

Expand All @@ -63,8 +66,17 @@ public HtmlFormat(Path outputPath, Env env, boolean testMode) {
f_testMode = testMode;
}

public HtmlFormat sources(List<DataSource> sources) {
public HtmlFormat sources(List<DataSourceType> sources) {
if (sources != null) {
m_geneSources = sources.stream()
.map((t) -> {
if (t.getDataSource() == DataSource.DPWG) {
return DataSource.DPWG;
} else {
return DataSource.CPIC;
}
})
.collect(Collectors.toSet());
m_sources = sources;
}
return this;
Expand Down Expand Up @@ -122,7 +134,7 @@ private Map<String,Object> compile(ReportContext reportContext) {
SortedSetMultimap<String, GeneReport> geneReportMap = TreeMultimap.create();
Map<String, Map<String, String>> functionMap = new HashMap<>();
for (DataSource source : new TreeSet<>(reportContext.getGeneReports().keySet())) {
if (!m_sources.contains(source)) {
if (!m_geneSources.contains(source)) {
continue;
}
for (GeneReport geneReport : reportContext.getGeneReports().get(source).values()) {
Expand Down Expand Up @@ -151,7 +163,7 @@ private Map<String,Object> compile(ReportContext reportContext) {
}

// skip gene reports that aren't related to any drugs
if (geneReport.getRelatedDrugs().size() == 0) {
if (geneReport.getRelatedDrugs().isEmpty()) {
continue;
}

Expand Down Expand Up @@ -225,7 +237,7 @@ private Map<String,Object> compile(ReportContext reportContext) {

// Section II: Prescribing Recommendations
SortedMap<String, Recommendation> recommendationMap = new TreeMap<>();
for (DataSource source : reportContext.getDrugReports().keySet()) {
for (DataSourceType source : reportContext.getDrugReports().keySet()) {
if (!m_sources.contains(source)) {
continue;
}
Expand Down
Loading

0 comments on commit f2e2be1

Please sign in to comment.