├── .gitignore ├── .travis.yml ├── README.md ├── bin └── kboom ├── boom-core ├── bin │ ├── Makefile │ └── pom.xml ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── monarchinitiative │ │ │ └── boom │ │ │ ├── compute │ │ │ ├── ProbabilisticGraphCalculator.java │ │ │ └── package-info.java │ │ │ ├── io │ │ │ ├── CliqueSolutionDotWriter.java │ │ │ ├── IDTools.java │ │ │ ├── LabelProvider.java │ │ │ ├── Loader.java │ │ │ ├── OWLLoader.java │ │ │ ├── ProbabilisticGraphParser.java │ │ │ └── package-info.java │ │ │ ├── model │ │ │ ├── CliqueSolution.java │ │ │ ├── EdgeProbabilityTable.java │ │ │ ├── EdgeType.java │ │ │ ├── LabelUtil.java │ │ │ ├── ProbabilisticEdge.java │ │ │ ├── ProbabilisticGraph.java │ │ │ └── package-info.java │ │ │ ├── package-info.java │ │ │ └── runner │ │ │ ├── MarkdownRunner.java │ │ │ └── RunEngine.java │ └── resources │ │ └── log4j.properties │ └── test │ ├── java │ └── org │ │ └── monarchinitiative │ │ └── owlbag │ │ └── compute │ │ └── ProbabilisticGraphCalculatorTest.java │ └── resources │ ├── basic-fp.obo │ ├── basic.obo │ ├── cases │ ├── xlid-ptable.tsv │ └── xlid.obo │ ├── clique-test.obo │ ├── disjoint_test.obo │ ├── log4j.properties │ ├── nosol.obo │ ├── ptable-asserted-subclass.tsv │ ├── ptable-basic.tsv │ ├── ptable-diseases.tsv │ ├── ptable-disjoint.tsv │ ├── ptable-false-positive.tsv │ ├── ptable-false-positive2.tsv │ ├── ptable-nosol.tsv │ ├── ptable-one-solution.tsv │ ├── ptable-override.tsv │ ├── ptable-reciprocal-conflict.tsv │ ├── ptable-trivial-4-combos.tsv │ ├── ptable-unsat-clique-test.tsv │ ├── ptable-unsat-clique-test2.tsv │ ├── ptable-unsatisfiable.tsv │ ├── trivial-4-combos.obo │ └── x-ontology-subclass.obo └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | catalog-v001.xml 2 | target/ 3 | .classpath 4 | .project 5 | .settings 6 | ./src/test/resources/catalog-v001.xml 7 | *iml 8 | .idea 9 | bin/*.jar 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | sudo: true 3 | jdk: 4 | - oraclejdk8 5 | 6 | branches: 7 | only: 8 | - master 9 | 10 | before_install: 11 | - "sudo apt-get install graphviz" 12 | - "which dot" 13 | 14 | after_success: 15 | - mvn clean cobertura:cobertura coveralls:report 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/monarch-initiative/kboom.svg?branch=master)](https://travis-ci.org/monarch-initiative/kboom) 2 | 3 | ## BOOM: Bayes OWL Ontology Merging 4 | 5 | BOOM is an ontology construction technique that combines deductive reasoning and probabilistic inference. It takes two or more ontologies linked by hypothetical axioms, and estimates the most likely unified logical ontology. 6 | 7 | ## k-BOOM 8 | 9 | k-BOOM is a version of BOOM that works by factorizing the probabilistic ontology into k submodules. It was used to build the [Mondo](http://obofoundry.org/ontology/mondo.html) merged disease ontology. 10 | 11 | For more information see: 12 | 13 | * Preprint: Mungall CJ, Koehler S, Robinson P, Holmes I, Haendel M. k-BOOM: A Bayesian approach to ontology structure inference, with applications in disease ontology construction. bioRxiv. 2019. https://www.biorxiv.org/content/10.1101/048843v3 14 | * [PhenoDay presentation](http://f1000research.com/slides/5-1648) 15 | 16 | To run: 17 | 18 | ``` 19 | mvn install 20 | bin/kboom -t all-ptable.tsv all.owl -o merged.owl 21 | ``` 22 | -------------------------------------------------------------------------------- /bin/kboom: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | DIRNAME=`dirname $0` 3 | #PATH_TO_ME=`which $0`; 4 | # Give a space-separated list of classpath items RELATIVE TO THE CURRENT SCRIPT 5 | # These will be resolved into absolute pathnames 6 | # Wildcards are allowed 7 | CLASSPATH_RELATIVE=boom.jar 8 | 9 | ## Check for Cygwin, use grep for a case-insensitive search 10 | IS_CYGWIN="FALSE" 11 | if uname | grep -iq cygwin; then 12 | IS_CYGWIN="TRUE" 13 | fi 14 | 15 | # If literal classpath values are needed, uncomment the line below 16 | # This can be useful if the classpath contains URLs 17 | # CLASSPATH_LITERAL="" 18 | 19 | # To set a specific default Java path, set the JAVAPATH variable below. 20 | # This value can be overridden with the -Jvm= option. 21 | # If JAVAPATH is not set, the script will use whatever version of Java is on the 22 | # path. If there is no copy of Java on the path, the JAVA_HOME environment 23 | # variable will be used. If that fails, we just use "java" in the hopes that the 24 | # failure message will make a little more sense. 25 | # JAVAPATH="java" 26 | 27 | if [ $IS_CYGWIN = "TRUE" ] 28 | then 29 | PATH_SEP=";" 30 | else 31 | PATH_SEP=":" 32 | fi 33 | 34 | JAVAARGS=" " 35 | CMDARGS=" " 36 | 37 | # Remove the name of this script from the end of the path 38 | PATH_TO_ME=`which $0`; 39 | PATH_TO_ME=`echo $PATH_TO_ME | sed -e "s/\(.*\)\/.*/\1/g"` 40 | 41 | if [ $IS_CYGWIN = "TRUE" ] 42 | then 43 | LAUNCHER_DIR="`cygpath --mixed $PATH_TO_ME`" 44 | else 45 | LAUNCHER_DIR="$PATH_TO_ME" 46 | fi 47 | 48 | 49 | # Just the name of the script. 50 | SCRIPTNAME=`echo $PATH_TO_ME | sed -e "s/.*\/\(.*\)/\1/g"` 51 | 52 | ## Add vmoptions to JAVAARGS if the proper file is available. 53 | if [ -e "$PATH_TO_ME/$SCRIPTNAME.vmoptions" ] 54 | then 55 | VMOPTIONS=`cat $PATH_TO_ME/$SCRIPTNAME.vmoptions` 56 | for OPTION in "$VMOPTIONS" 57 | do 58 | JAVAARGS="$JAVAARGS '${OPTION}'" 59 | done 60 | else 61 | if [ $KBOOM_MEMORY ] 62 | then 63 | JAVAARGS="$JAVAARGS -Xmx$KBOOM_MEMORY" 64 | else 65 | JAVAARGS="$JAVAARGS -Xmx12G" 66 | fi 67 | fi 68 | 69 | ## Walk through all the command line arguments and add them to 70 | ## the CMDARGS depending. 71 | 72 | for ARG in "$@" 73 | do 74 | CMDARGS="${CMDARGS} '${ARG}'" 75 | shift 1; 76 | done 77 | 78 | ## Add to CLASSPATH using CLASSPATH_RELATIVE. 79 | CLASSPATH="" 80 | for ARG in "$CLASSPATH_RELATIVE" 81 | do 82 | DEREFERENCED_CLASSPATH=`ls -1 -L $PATH_TO_ME/$ARG | grep -v ontologyrelease` 83 | for CP_ENTRY in $DEREFERENCED_CLASSPATH 84 | do 85 | if [ $IS_CYGWIN = "TRUE" ] 86 | then 87 | CP_ENTRY="`cygpath --mixed \"$CP_ENTRY\"`" 88 | fi 89 | if [ -z "$CLASSPATH" ] 90 | then 91 | CLASSPATH="$CP_ENTRY" 92 | else 93 | CLASSPATH="$CLASSPATH$PATH_SEP$CP_ENTRY" 94 | fi 95 | done 96 | done 97 | 98 | ## Add to CLASSPATH using CLASSPATH_LITERAL. 99 | if [ -n "$CLASSPATH_LITERAL" ] 100 | then 101 | for CP_ENTRY in $CLASSPATH_LITERAL 102 | do 103 | if [ -z "$CLASSPATH" ] 104 | then 105 | CLASSPATH="$CP_ENTRY" 106 | else 107 | CLASSPATH="$CLASSPATH$PATH_SEP$CP_ENTRY" 108 | fi 109 | done 110 | fi 111 | 112 | ## Figure out which java to use. 113 | if [ -z "$JAVAPATH" ] 114 | then 115 | JAVAPATH=`which java` 116 | if [ -z "$JAVAPATH" ] 117 | then 118 | if [ -n "$JAVA_HOME" && -e "$JAVA_HOME" ] 119 | then 120 | JAVAPATH=$JAVA_HOME/bin/java 121 | else 122 | JAVAPATH="java" 123 | fi 124 | fi 125 | fi 126 | 127 | ## Assemble and run the final command. 128 | CMD="\"$JAVAPATH\" -Xms2048M -DentityExpansionLimit=4086000 -Djava.awt.headless=true -classpath \"$CLASSPATH\" -DlauncherDir=\"$LAUNCHER_DIR\" $JAVAARGS org.monarchinitiative.boom.runner.RunEngine $CMDARGS" 129 | 130 | ## DEBUG 131 | ## Let's see a little of the environment if we declare DEBUG=1. 132 | if [ $DEBUG ] 133 | then 134 | for MYVAR in DEBUG PATH_TO_ME SCRIPTNAME DIRNAME JAVAARGS CMDARGS CLASSPATH_RELATIVE CMD 135 | do 136 | LETVAR=`echo "$"$MYVAR` 137 | TMPVAR=`eval echo $LETVAR` 138 | echo "${MYVAR}: \"${TMPVAR}\"" 139 | done 140 | fi 141 | 142 | ## Run the final command. 143 | if [ $DEBUG ] 144 | then 145 | echo "$CMD" 146 | fi 147 | sh -c "$CMD" 148 | -------------------------------------------------------------------------------- /boom-core/bin/Makefile: -------------------------------------------------------------------------------- 1 | OBO := http://purl.obolibrary.org/obo 2 | 3 | src/test/resources/ontologies/%.obo: 4 | wget $(OBO)/$*.obo -O $@ 5 | 6 | src/test/resources/data/%.owl: 7 | wget $(OBO)/upheno/data/$*.owl -O $@ 8 | 9 | src/test/resources/data/%.ttl: 10 | wget $(OBO)/upheno/data/$*.ttl -O $@ 11 | -------------------------------------------------------------------------------- /boom-core/bin/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | owlsim 6 | org.monarchinitiative.owlsim 7 | 3.0-SNAPSHOT 8 | 9 | owlsim-core 10 | jar 11 | owlsim-core 12 | 13 | 14 | 2.11.2 15 | 16 | 17 | 18 | 19 | org.apache.jena 20 | jena-core 21 | ${jena.version} 22 | 23 | 24 | org.apache.jena 25 | jena-arq 26 | ${jena.version} 27 | 28 | 29 | net.sourceforge.owlapi 30 | owlapi-apibinding 31 | ${owlapi.version} 32 | 33 | 34 | net.sourceforge.owlapi 35 | owlapi-api 36 | ${owlapi.version} 37 | 38 | 39 | net.sourceforge.owlapi 40 | owlapi-contract 41 | ${owlapi.version} 42 | 43 | 44 | net.sourceforge.owlapi 45 | owlapi-distribution 46 | ${owlapi.version} 47 | 48 | 49 | net.sourceforge.owlapi 50 | owlapi-impl 51 | ${owlapi.version} 52 | 53 | 54 | net.sourceforge.owlapi 55 | owlapi-parsers 56 | ${owlapi.version} 57 | 58 | 59 | net.sourceforge.owlapi 60 | owlapi-tools 61 | ${owlapi.version} 62 | 63 | 64 | log4j 65 | log4j 66 | 1.2.17 67 | 68 | 69 | mail 70 | javax.mail 71 | 72 | 73 | jms 74 | javax.jms 75 | 76 | 77 | jmxtools 78 | com.sun.jdmk 79 | 80 | 81 | jmxri 82 | com.sun.jmx 83 | 84 | 85 | 86 | 87 | org.apache.ant 88 | ant 89 | 1.8.2 90 | 91 | 92 | commons-io 93 | commons-io 94 | 2.2 95 | 96 | 97 | org.semanticweb.elk 98 | elk-owlapi 99 | 0.4.1 100 | 101 | 102 | com.google.code.gson 103 | gson 104 | 2.2.4 105 | 106 | 107 | net.sourceforge.owlapi 108 | jfact 109 | 1.0.0 110 | 111 | 112 | jline 113 | jline 114 | 0.9.93 115 | 116 | 117 | junit 118 | junit 119 | 120 | 121 | 122 | 123 | org.apache.geronimo.specs 124 | geronimo-javamail_1.4_spec 125 | 1.6 126 | 127 | 128 | com.googlecode.javaewah 129 | JavaEWAH 130 | 0.7.7 131 | 132 | 133 | org.apache.commons 134 | commons-math3 135 | 3.3 136 | 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /boom-core/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | boom 6 | org.monarchinitiative.boom 7 | 1.0-SNAPSHOT 8 | 9 | boom-core 10 | jar 11 | boom-core 12 | 13 | 14 | 2.11.2 15 | 16 | 17 | 18 | 19 | 20 | 21 | org.apache.maven.plugins 22 | maven-assembly-plugin 23 | 24 | boom 25 | false 26 | false 27 | ${project.parent.basedir}/bin 28 | 29 | jar-with-dependencies 30 | 31 | 32 | 33 | true 34 | org.monarchinitiative.boom.compute.runner.RunEngine 35 | 36 | 37 | 38 | 39 | 40 | make-assembly 41 | package 42 | 43 | single 44 | 45 | 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-failsafe-plugin 51 | 2.18.1 52 | 53 | 54 | 55 | integration-test 56 | verify 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.apache.jena 67 | jena-core 68 | ${jena.version} 69 | 70 | 71 | org.apache.jena 72 | jena-arq 73 | ${jena.version} 74 | 75 | 76 | net.sourceforge.owlapi 77 | owlapi-apibinding 78 | ${owlapi.version} 79 | 80 | 81 | net.sourceforge.owlapi 82 | owlapi-api 83 | ${owlapi.version} 84 | 85 | 86 | net.sourceforge.owlapi 87 | owlapi-contract 88 | ${owlapi.version} 89 | 90 | 91 | net.sourceforge.owlapi 92 | owlapi-distribution 93 | ${owlapi.version} 94 | 95 | 96 | net.sourceforge.owlapi 97 | owlapi-impl 98 | ${owlapi.version} 99 | 100 | 101 | net.sourceforge.owlapi 102 | owlapi-parsers 103 | ${owlapi.version} 104 | 105 | 106 | net.sourceforge.owlapi 107 | owlapi-tools 108 | ${owlapi.version} 109 | 110 | 111 | log4j 112 | log4j 113 | 1.2.17 114 | 115 | 116 | mail 117 | javax.mail 118 | 119 | 120 | jms 121 | javax.jms 122 | 123 | 124 | jmxtools 125 | com.sun.jdmk 126 | 127 | 128 | jmxri 129 | com.sun.jmx 130 | 131 | 132 | 133 | 134 | org.apache.ant 135 | ant 136 | 1.8.2 137 | 138 | 139 | commons-io 140 | commons-io 141 | 2.2 142 | 143 | 144 | org.semanticweb.elk 145 | elk-owlapi 146 | 0.4.3 147 | 148 | 149 | com.google.code.gson 150 | gson 151 | 2.2.4 152 | 153 | 154 | net.sourceforge.owlapi 155 | jfact 156 | 1.0.0 157 | 158 | 159 | jline 160 | jline 161 | 0.9.93 162 | 163 | 164 | junit 165 | junit 166 | 167 | 168 | 169 | 170 | org.apache.geronimo.specs 171 | geronimo-javamail_1.4_spec 172 | 1.6 173 | 174 | 175 | com.googlecode.javaewah 176 | JavaEWAH 177 | 0.7.7 178 | 179 | 180 | org.apache.commons 181 | commons-math3 182 | 3.3 183 | 184 | 185 | commons-validator 186 | commons-validator 187 | 1.4.0 188 | 189 | 190 | com.beust 191 | jcommander 192 | 1.48 193 | 194 | 195 | com.google.guava 196 | guava 197 | 19.0 198 | 199 | 200 | 201 | 202 | 203 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/compute/ProbabilisticGraphCalculator.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.compute; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.HashSet; 7 | import java.util.List; 8 | import java.util.Map; 9 | import java.util.Set; 10 | import java.util.stream.Collectors; 11 | 12 | import org.apache.log4j.Logger; 13 | import org.monarchinitiative.boom.io.LabelProvider; 14 | import org.monarchinitiative.boom.model.CliqueSolution; 15 | import org.monarchinitiative.boom.model.EdgeType; 16 | import org.monarchinitiative.boom.model.ProbabilisticEdge; 17 | import org.monarchinitiative.boom.model.ProbabilisticGraph; 18 | import org.semanticweb.elk.owlapi.ElkReasonerFactory; 19 | import org.semanticweb.owlapi.io.OWLObjectRenderer; 20 | import org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterOWLSyntaxOWLObjectRendererImpl; 21 | import org.semanticweb.owlapi.model.*; 22 | import org.semanticweb.owlapi.model.parameters.Imports; 23 | import org.semanticweb.owlapi.reasoner.Node; 24 | import org.semanticweb.owlapi.reasoner.OWLReasoner; 25 | import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; 26 | 27 | import com.google.common.base.Optional; 28 | import com.google.common.base.Strings; 29 | import com.google.common.collect.Sets; 30 | 31 | import uk.ac.manchester.cs.owlapi.modularity.ModuleType; 32 | import uk.ac.manchester.cs.owlapi.modularity.SyntacticLocalityModuleExtractor; 33 | 34 | /** 35 | * 36 | * Calculates the most probably graph, given a set of edge probabilities, and 37 | * a set of logical edges 38 | * 39 | * @author cjm 40 | * 41 | */ 42 | public class ProbabilisticGraphCalculator { 43 | 44 | private static Logger LOG = Logger.getLogger(ProbabilisticGraphCalculator.class); 45 | 46 | ProbabilisticGraph probabilisticGraph; 47 | OWLOntology sourceOntology; 48 | OWLReasonerFactory reasonerFactory = new ElkReasonerFactory(); 49 | OWLObjectRenderer renderer; 50 | Set filterOnClasses; 51 | Set filterOnRootClasses; 52 | public boolean isExperimental = false; // TEMPORARY 53 | 54 | 55 | //OWLReasonerFactory reasonerFactory = new org.semanticweb.HermiT.Reasoner.ReasonerFactory(); 56 | 57 | /** 58 | * Number of probabilistic edges after which a clique is broken down using heuristics 59 | */ 60 | public int maxProbabilisticEdges = 10; 61 | 62 | /** 63 | * 64 | */ 65 | public int cliqueSplitSize = 6; 66 | 67 | /** 68 | * Number of probabilistic edges below which no attempt will be made to resolve clique 69 | */ 70 | public int minProbabilisticEdges = 0; 71 | 72 | public ProbabilisticGraphCalculator(OWLOntology sourceOntology) { 73 | super(); 74 | this.sourceOntology = sourceOntology; 75 | LabelProvider provider = new LabelProvider(sourceOntology); 76 | renderer = 77 | new ManchesterOWLSyntaxOWLObjectRendererImpl(); 78 | renderer.setShortFormProvider(provider); 79 | } 80 | 81 | 82 | public ProbabilisticGraphCalculator(OWLOntology owlOntology, 83 | ProbabilisticGraph pg) { 84 | this(owlOntology); 85 | setProbabilisticGraph(pg); 86 | } 87 | 88 | 89 | /** 90 | * @return the sourceOntology 91 | */ 92 | public OWLOntology getSourceOntology() { 93 | return sourceOntology; 94 | } 95 | 96 | 97 | /** 98 | * @param sourceOntology the sourceOntology to set 99 | */ 100 | public void setSourceOntology(OWLOntology sourceOntology) { 101 | this.sourceOntology = sourceOntology; 102 | } 103 | 104 | 105 | /** 106 | * @return ontology manager 107 | */ 108 | public OWLOntologyManager getOWLOntologyManager() { 109 | return sourceOntology.getOWLOntologyManager(); 110 | } 111 | /** 112 | * @return data factory 113 | */ 114 | public OWLDataFactory getOWLDataFactory() { 115 | return getOWLOntologyManager().getOWLDataFactory(); 116 | } 117 | 118 | /** 119 | * @return the reasonerFactory 120 | */ 121 | public OWLReasonerFactory getReasonerFactory() { 122 | return reasonerFactory; 123 | } 124 | 125 | /** 126 | * @param reasonerFactory the reasonerFactory to set 127 | */ 128 | public void setReasonerFactory(OWLReasonerFactory reasonerFactory) { 129 | this.reasonerFactory = reasonerFactory; 130 | } 131 | 132 | 133 | 134 | /** 135 | * @return the maxProbabilisticEdges 136 | */ 137 | public int getMaxProbabilisticEdges() { 138 | return maxProbabilisticEdges; 139 | } 140 | 141 | /** 142 | * @param maxProbabilisticEdges the maxProbabilisticEdges to set 143 | */ 144 | public void setMaxProbabilisticEdges(int maxProbabilisticEdges) { 145 | this.maxProbabilisticEdges = maxProbabilisticEdges; 146 | } 147 | 148 | 149 | 150 | /** 151 | * @return the minProbabilisticEdges 152 | */ 153 | public int getMinProbabilisticEdges() { 154 | return minProbabilisticEdges; 155 | } 156 | 157 | 158 | /** 159 | * @param minProbabilisticEdges the minProbabilisticEdges to set 160 | */ 161 | public void setMinProbabilisticEdges(int minProbabilisticEdges) { 162 | this.minProbabilisticEdges = minProbabilisticEdges; 163 | } 164 | 165 | 166 | 167 | /** 168 | * @return the cliqueSplitSize 169 | */ 170 | public int getCliqueSplitSize() { 171 | return cliqueSplitSize; 172 | } 173 | 174 | 175 | /** 176 | * @param cliqueSplitSize the cliqueSplitSize to set 177 | */ 178 | public void setCliqueSplitSize(int cliqueSplitSize) { 179 | this.cliqueSplitSize = cliqueSplitSize; 180 | } 181 | 182 | 183 | /** 184 | * @param filterOnClasses the filterOnClasses to set 185 | */ 186 | public void setFilterOnClasses(Set filterOnClasses) { 187 | this.filterOnClasses = filterOnClasses; 188 | } 189 | 190 | 191 | 192 | /** 193 | * @param filterOnRootClasses the filterOnRootClasses to set 194 | */ 195 | public void setFilterOnRootClasses(Set filterOnRootClasses) { 196 | this.filterOnRootClasses = filterOnRootClasses; 197 | } 198 | 199 | 200 | /** 201 | * @return the graph 202 | */ 203 | public ProbabilisticGraph getProbabilisticGraph() { 204 | return probabilisticGraph; 205 | } 206 | 207 | /** 208 | * @param graph the graph to set 209 | */ 210 | public void setProbabilisticGraph(ProbabilisticGraph graph) { 211 | this.probabilisticGraph = graph; 212 | } 213 | 214 | 215 | /** 216 | * @param baseOntology 217 | * @param parentOntology 218 | */ 219 | public void addImport(OWLOntology baseOntology, OWLOntology parentOntology) { 220 | Optional ontologyIRI = baseOntology.getOntologyID().getOntologyIRI(); 221 | OWLImportsDeclaration d = getOWLDataFactory().getOWLImportsDeclaration(ontologyIRI.orNull()); 222 | AddImport ai = new AddImport(parentOntology, d); 223 | getOWLOntologyManager().applyChange(ai); 224 | 225 | } 226 | 227 | /** 228 | * For all DisjointClasses(A B), 229 | * materialize DisjointClasses(a b), for a in Sub(A) and b in Sub(B) 230 | * 231 | * This ensures that module extraction will have disjointness axioms even when parents omitted 232 | */ 233 | public void propagateDownDisjointnessAxioms() { 234 | 235 | LOG.info("Propagating down disjointness axioms..."); 236 | OWLReasoner reasoner = getReasonerFactory().createReasoner(sourceOntology); 237 | LOG.info("Created reasoner..."); 238 | 239 | Set newAxioms = new HashSet<>(); 240 | for (OWLDisjointClassesAxiom a : sourceOntology.getAxioms(AxiomType.DISJOINT_CLASSES)) { 241 | Set cs = a.getClassExpressions().stream(). 242 | filter(x -> !x.isAnonymous()).map(x -> x.asOWLClass()).collect(Collectors.toSet()); 243 | for (OWLClass c : cs) { 244 | Set csubs = reasoner.getSubClasses(c, false).getFlattened(); 245 | csubs.add(c); 246 | csubs.remove(getOWLDataFactory().getOWLNothing()); 247 | for (OWLClass d : cs) { 248 | 249 | // symmetrical pairs: only perform once for each pair 250 | if (c.compareTo(d) > 0) { 251 | Set dsubs = reasoner.getSubClasses(d, false).getFlattened(); 252 | dsubs.add(d); 253 | dsubs.remove(getOWLDataFactory().getOWLNothing()); 254 | 255 | for (OWLClass csub : csubs) { 256 | for (OWLClass dsub : dsubs) { 257 | OWLDisjointClassesAxiom ax = getOWLDataFactory().getOWLDisjointClassesAxiom(csub, dsub); 258 | 259 | //LOG.info("PROPAGATED: "+ax); 260 | newAxioms.add(ax); 261 | } 262 | } 263 | 264 | 265 | } 266 | } 267 | } 268 | } 269 | reasoner.dispose(); 270 | LOG.info("ADDING Propagated disjointness axioms: "+newAxioms.size()); 271 | getOWLOntologyManager().addAxioms(sourceOntology, newAxioms); 272 | LOG.info("ADDED Propagated disjointness axioms: "+newAxioms.size()); 273 | 274 | 275 | } 276 | 277 | /** 278 | * We find cliques by first assuming any probabilistic edge for (A,B) is set such that 279 | * Pr(Equiv(A,B)) == 1, and then use a reasoner to find cliques/nodes 280 | * 281 | * Each such clique can be treated as a distinct subgraph and resolved independently 282 | * of the others 283 | * 284 | * @return clique nodes 285 | * @throws OWLOntologyCreationException 286 | */ 287 | public Set> findCliques() throws OWLOntologyCreationException { 288 | 289 | LOG.info("Finding cliques..."); 290 | OWLOntology dynamicOntology; 291 | 292 | dynamicOntology = getOWLOntologyManager().createOntology(); 293 | OWLOntology coreOntology = 294 | getOWLOntologyManager().createOntology(IRI.create("http://x.org")); 295 | for ( OWLAxiom a : sourceOntology.getAxioms(Imports.INCLUDED)) { 296 | // we exclude disjoint axioms from the clique finding set; 297 | // this is because the clique strategy depends on assuming 298 | // equivalence for every potential equivalence, likely violating 299 | // disjointness assumptions 300 | if (a instanceof OWLDisjointClassesAxiom) { 301 | continue; 302 | } 303 | getOWLOntologyManager().addAxiom(coreOntology, a); 304 | } 305 | addImport(coreOntology, dynamicOntology); 306 | LOG.info("Creating reasoner..."); 307 | OWLReasoner reasoner = getReasonerFactory().createReasoner(dynamicOntology); 308 | 309 | // first find any pr edges that are overridden by logical axiom entailments. 310 | // note for the mapping scenario, this should only happen when there are 311 | // asserted logical axioms across ontologies. 312 | // For the MonDO pipeline, this includes the OMIM clusters that are 313 | // later made equivalent with DO 314 | LOG.info("Finding weighted edges that are inferred (p=1)..."); 315 | Set rmEdges = findEntailedProbabilisticEdges(probabilisticGraph, reasoner); 316 | if (rmEdges.size() > 0) { 317 | for (ProbabilisticEdge e : rmEdges) { 318 | LOG.info("Pruning edge with logic entailment: "+render(e)); 319 | } 320 | if (isExperimental) { 321 | probabilisticGraph.getProbabilisticEdges().removeAll(rmEdges); 322 | } 323 | else { 324 | LOG.error("FIX Me!!"); 325 | } 326 | } 327 | 328 | LOG.info("Using weighted edges to find cliques... pEdges="+probabilisticGraph.getProbabilisticEdges().size()); 329 | int nEquiv = 0; 330 | // assume every probabilistic edge is an equivalence axiom 331 | for (ProbabilisticEdge e : probabilisticGraph.getProbabilisticEdges()) { 332 | if (e.getProbabilityTable().getTypeProbabilityMap().get(EdgeType.NONE) < 1.0) { 333 | OWLEquivalentClassesAxiom ax = translateEdgeToEquivalenceAxiom(e); 334 | getOWLOntologyManager().addAxiom(dynamicOntology, ax); 335 | nEquiv++; 336 | } 337 | } 338 | reasoner.flush(); 339 | 340 | LOG.info("Finding equivalence nodes... eEdges = "+nEquiv); 341 | Set> cliques = new HashSet<>(); 342 | int maxSize = 0; 343 | int i=0; 344 | for (OWLClass c : sourceOntology.getClassesInSignature()) { 345 | i++; 346 | Node n = reasoner.getEquivalentClasses(c); 347 | int size = n.getSize(); 348 | if (filterOnRootClasses != null && filterOnRootClasses.size() > 0) { 349 | if (!reasoner.getSuperClasses(c, false).getFlattened().containsAll(filterOnRootClasses)) { 350 | LOG.info("SKIPPING: "+c+" as not in set"); 351 | continue; 352 | } 353 | LOG.info("INCLUDING: "+c); 354 | } 355 | if (size > maxSize) { 356 | maxSize = size; 357 | LOG.info("CURRENT MAX SIZE: "+maxSize+" // "+n+" :: processed " + i +"/" + sourceOntology.getClassesInSignature().size()); 358 | } 359 | if (size > 1) { 360 | cliques.add(n); 361 | } 362 | 363 | } 364 | 365 | LOG.info("|Cliques| = "+cliques.size()+" (first pass)"); 366 | // split cliques 367 | Set> removedCliques = new HashSet<>(); 368 | Set> newCliques = new HashSet<>(); 369 | 370 | // iterate through cliques and heuristically split 371 | // any that are too large, for which removing a single connection 372 | // can result in two semantically non-overlapping sub-cliques. 373 | // the removed edge is a candidate error 374 | for (Node node : cliques) { 375 | int nodeSize = node.getSize(); 376 | // TODO - less arbitrary sizes 377 | if (nodeSize > cliqueSplitSize) { 378 | LOG.info("Candidate for splitting: "+render(node.getRepresentativeElement())+" |N|="+node.getSize()); 379 | Set clzs = node.getEntities(); 380 | Set badEdges = new HashSet<>(); 381 | for (ProbabilisticEdge e : probabilisticGraph.getProbabilisticEdges()) { 382 | if (clzs.contains(e.getSourceClass())) { 383 | OWLEquivalentClassesAxiom ax = translateEdgeToEquivalenceAxiom(e); 384 | getOWLOntologyManager().removeAxiom(dynamicOntology, ax); 385 | reasoner.flush(); 386 | Node newLeftNode = reasoner.getEquivalentClasses(e.getSourceClass()); 387 | Node newRightNode = reasoner.getEquivalentClasses(e.getTargetClass()); 388 | // TODO - do not hardcode 389 | if (newLeftNode.getSize() >= 5 && newRightNode.getSize() >= 5) { 390 | double sim = getSimilarity(e.getSourceClass(), e.getTargetClass(), reasoner); 391 | LOG.debug("Similarity = "+sim+" For: "+e); 392 | if (sim < 0.25) { // TODO - no hardcoding 393 | badEdges.add(e); 394 | LOG.info(" Splitting: "+render(e)+" Similarity="+sim+" subCliqueSizes: "+ 395 | newLeftNode.getSize() +","+newRightNode.getSize()); 396 | } 397 | } 398 | getOWLOntologyManager().addAxiom(dynamicOntology, ax); 399 | } 400 | } 401 | if (badEdges.size() > 0) { 402 | for (ProbabilisticEdge e : badEdges) { 403 | OWLEquivalentClassesAxiom ax = translateEdgeToEquivalenceAxiom(e); 404 | getOWLOntologyManager().removeAxiom(dynamicOntology, ax); 405 | } 406 | reasoner.flush(); 407 | removedCliques.add(node); 408 | for (OWLClass c : clzs) { 409 | newCliques.add(reasoner.getEquivalentClasses(c)); 410 | } 411 | LOG.info("prEdges (before splits):"+probabilisticGraph.getProbabilisticEdges().size()); 412 | probabilisticGraph.removeEdges(badEdges); 413 | LOG.info("prEdges (after splits):"+probabilisticGraph.getProbabilisticEdges().size()); 414 | } 415 | } 416 | } 417 | 418 | if (removedCliques.size() > 0) { 419 | LOG.info("REMOVING: "+removedCliques); 420 | LOG.info("ADDING: "+newCliques); 421 | cliques.removeAll(removedCliques); 422 | cliques.addAll(newCliques); 423 | } 424 | LOG.info("|Cliques| = "+cliques.size()+" (after splitting)"); 425 | 426 | 427 | int maxCliqueSize = 0; 428 | for (Node n : cliques) { 429 | if (n.getSize() > maxCliqueSize) 430 | maxCliqueSize = n.getSize(); 431 | } 432 | 433 | 434 | reasoner.dispose(); 435 | LOG.info("MaxCliqueSize=" + maxCliqueSize); 436 | LOG.info("|Cliques|=" + cliques.size()); 437 | return cliques; 438 | } 439 | 440 | private double getSimilarity(OWLClass c, OWLClass d, OWLReasoner reasoner) { 441 | Set ca = reasoner.getSuperClasses(c, false).getFlattened(); 442 | Set da = reasoner.getSuperClasses(d, false).getFlattened(); 443 | return Sets.intersection(ca, da).size() / (double)(Sets.union(ca, da).size()); 444 | } 445 | 446 | private OWLEquivalentClassesAxiom translateEdgeToEquivalenceAxiom(ProbabilisticEdge e) { 447 | return getOWLDataFactory().getOWLEquivalentClassesAxiom(e.getSourceClass(), 448 | e.getTargetClass()); 449 | } 450 | 451 | /** 452 | * Solves all cliques and adds resulting axioms back into main ontology 453 | * @return clique solutions 454 | * 455 | * @throws OWLOntologyCreationException 456 | */ 457 | public Set solveAllCliques() throws OWLOntologyCreationException { 458 | propagateDownDisjointnessAxioms(); 459 | Set> cliques = findCliques(); 460 | Set axioms = new HashSet(); 461 | Set rpts = new HashSet(); 462 | int ctr = 0; 463 | LOG.info("Solving cliques..."); 464 | for (Node n : cliques) { 465 | 466 | // user option: only process nodes with desired classes 467 | if (filterOnClasses != null && filterOnClasses.size() > 0) { 468 | if (n.getEntities().stream().filter( c -> filterOnClasses.contains(c)).count() == 0) { 469 | LOG.info("Skipping: "+render(n.getEntities())); 470 | continue; 471 | } 472 | } 473 | 474 | ctr++; 475 | LOG.info("NUM:"+ctr+"/"+cliques.size()); 476 | 477 | // SOLVE CLIQUE 478 | long t1 = System.currentTimeMillis(); 479 | CliqueSolution rpt = solveClique(n); 480 | long t2 = System.currentTimeMillis(); 481 | 482 | // add solution report 483 | if (rpt != null) { 484 | rpt.timeToSolve = t2-t1; 485 | rpts.add(rpt); 486 | if (rpt.axioms != null) { 487 | axioms.addAll(rpt.axioms); 488 | } 489 | } 490 | } 491 | getOWLOntologyManager().addAxioms(sourceOntology, axioms); 492 | return rpts; 493 | } 494 | 495 | /** 496 | * Solves a clique (subgraph consisting of maximal set of nodes that are either 497 | * logically equivalent or have a probability of being equivalent) 498 | * 499 | * The clique is solved by testing all logically permissible sets of combinations 500 | * of logical relationships between all members, and determining the probability of 501 | * each such combination. 502 | * 503 | * @param n 504 | * @return clique solution 505 | * @throws OWLOntologyCreationException 506 | */ 507 | public CliqueSolution solveClique(Node n) throws OWLOntologyCreationException { 508 | LOG.info("SOLVING CLIQUE: "+n); 509 | 510 | // initialize 511 | OWLOntologyManager mgr = getOWLOntologyManager(); 512 | Set clzs = n.getEntities(); 513 | ProbabilisticGraph subPrGraph = getProbabilisticGraphModule(n); 514 | 515 | // candidate solution 516 | CliqueSolution cliqSoln = new CliqueSolution(); 517 | cliqSoln.cliqueId = n.getRepresentativeElement().getIRI().toString(); 518 | cliqSoln.size = n.getEntities().size(); 519 | cliqSoln.solved = false; // false by default, until a solution is found 520 | cliqSoln.classes = clzs; 521 | cliqSoln.members = 522 | clzs.stream().map( (OWLClass c) -> c.getIRI().toString()).collect(Collectors.toSet()); 523 | cliqSoln.subGraph = subPrGraph; 524 | cliqSoln.initialNumberOfProbabilisticEdges = subPrGraph.getProbabilisticEdges().size(); 525 | 526 | if (cliqSoln.initialNumberOfProbabilisticEdges < minProbabilisticEdges) { 527 | LOG.info(" prEdges = subPrGraph.getProbabilisticEdges(); 589 | 590 | // the clique has a logical part, which stays constant, 591 | // and a probabilistic part, which we test all combinations of 592 | OWLOntology logicalOntology = mgr.createOntology(subPrGraph.getLogicalEdges()); 593 | // probOntology contains candidate axioms, to be tested for satisfiability 594 | OWLOntology candidateOntology = mgr.createOntology(); 595 | addImport(logicalOntology, candidateOntology); 596 | 597 | // we create a new reasoner instance for every clique 598 | OWLReasoner reasoner = reasonerFactory.createReasoner(candidateOntology); 599 | 600 | Map> assertedSuperClassesMap = new HashMap<>(); 601 | for (OWLClass c : n.getEntities()) { 602 | assertedSuperClassesMap.put(c, reasoner.getSuperClasses(c, false).getFlattened()); 603 | } 604 | 605 | // for debug purposes 606 | Set disjointAxioms = 607 | logicalOntology.getAxioms(AxiomType.DISJOINT_CLASSES); 608 | if (disjointAxioms.size() > 0) { 609 | LOG.info("Disjointness Axioms in module: "+disjointAxioms.size()); 610 | } 611 | 612 | int N = prEdges.size(); 613 | LOG.info("|WeightedEdges|="+N); 614 | EdgeType[] etypes = EdgeType.values(); 615 | int M = etypes.length; // currently M=4 616 | //LOG.info("M="+M); 617 | int NUM_STATES = (int) Math.pow(M, N); 618 | 619 | LOG.info("STATES="+NUM_STATES); 620 | // debug 621 | for (OWLClass c : n.getEntities()) { 622 | LOG.info(" CLIQUE MEMBER:"+render(c)); 623 | } 624 | 625 | OWLAxiom[][] axiomIndex = subPrGraph.getAxiomIndex(); 626 | double[][] probabilityIndex = subPrGraph.getProbabilityIndex(); 627 | 628 | // test the probability of every combo of axioms 629 | // 4^N combinatorial states, each state representing an axiom state (<,>,=,null) 630 | double maxJointProbability = 0; 631 | double sumOfJointProbabilities = 0; 632 | Map stateScoreMap = new HashMap(); 633 | Set currentBestCombinationOfAxioms = new HashSet(); 634 | int numValidCombos = 0; 635 | //Set prevAxioms = new HashSet(); 636 | 637 | // for reporting purposes 638 | int numBelowProbThreshold = 0; 639 | int numWithInvalidSubClass = 0; 640 | int numWithInvalidEquivClass = 0; 641 | int numEquivInSameOnt = 0; 642 | int numUnsats = 0; 643 | int numFilteredByProb = 0; 644 | int numViolatedSubClass = 0; 645 | int numMissingEquivClass = 0; 646 | int numReasonerCalls = 0; 647 | 648 | for (int s=0; s axiomCombo = new HashSet(); 665 | boolean isZeroProbability = false; 666 | double jointProbability = 1; 667 | 668 | // iterate through each prEdge, and assign it one of 4 possible states 669 | for (int ei = 0; ei < N; ei++) { 670 | char sc = states[ei]; 671 | int j = Character.getNumericValue(sc); 672 | double pr = probabilityIndex[ei][j]; 673 | //LOG.info("xxxx ei="+ei+"/"+N+" jp="+jointProbability+" pr="+pr+" state="+new String(states)+" mjp="+maxJointProbability); 674 | // TODO: refactor to use logs; 675 | // not urgent as we don't expect underflows 676 | jointProbability *= pr; 677 | 678 | // TODO: change threshold 679 | if (pr < 0.001 || jointProbability < maxJointProbability) { 680 | //LOG.info("xxxx Skipping Pr="+pr+" because jointProb "+jointProbability+" < "+maxJointProbability+" // pr="+pr); 681 | // we do not progress any further if it is impossible to beat the 682 | // current best, or if the end result will be below a threshold 683 | isZeroProbability = true; 684 | //jointProbability = 0; 685 | numFilteredByProb++; 686 | break; 687 | } 688 | if (jointProbability < Math.pow(0.01, N)) { 689 | isZeroProbability = true; 690 | jointProbability = 0; 691 | LOG.info("Skipping; Joint probability="+jointProbability); 692 | numBelowProbThreshold++; 693 | break; 694 | } 695 | OWLAxiom ax = axiomIndex[ei][j]; 696 | if (ax != null) 697 | axiomCombo.add(ax); 698 | } 699 | if (jointProbability == 0 || jointProbability < maxJointProbability) { 700 | //LOG.info("xxxx moving into next state, as jointProb too low: "+jointProbability); 701 | if (jointProbability > 0.0) { 702 | stateScoreMap.put(s, jointProbability); 703 | } 704 | continue; 705 | } 706 | // TEST CONSISTENCY: 707 | 708 | // reset 709 | mgr.removeAxioms(candidateOntology, candidateOntology.getAxioms()); 710 | 711 | mgr.addAxioms(candidateOntology, axiomCombo); 712 | //LOG.info("CANDIDATE COMBO:"+new String(states)+" "+axiomCombo+" Pr="+jointProbability); 713 | //prevAxioms = new HashSet(axioms); 714 | reasoner.flush(); 715 | 716 | 717 | // TODO: call testForInvalidEquivalencies() //DRY 718 | // first test to make sure that no classes from the same ontology 719 | // are inferred to be identical 720 | // TODO: make this a more generic procedure whereby any set of classes 721 | // can be declared to be in an all-different set 722 | for (OWLClass c : n.getEntities()) { 723 | for (OWLClass d : n.getEntities()) { 724 | if (c.equals(d)) 725 | continue; 726 | 727 | if (isInSameOntology(c, d)) { 728 | // LOG.info("Same ontology: "+c+" "+d); 729 | if (reasoner.getEquivalentClasses(c).contains(d)) { 730 | //LOG.info(" xxxx INVALID: "+c+"=="+d); 731 | isZeroProbability = true; 732 | jointProbability = 0; 733 | numEquivInSameOnt++; 734 | break; 735 | } 736 | if (reasoner.getSuperClasses(c, false).containsEntity(d)) { 737 | if (!assertedSuperClassesMap.get(c).contains(d)) { 738 | // c and d are in the same ontology, and 739 | // c is inferred to be a subclass of d in this configuration 740 | // and this was not previously asserted 741 | //LOG.info(" ENTAILED: "+c+" SubClassOf "+d); 742 | // TODO - configure penalty by ontology; 743 | // e.g. DOID may be expected to have missing links 744 | jointProbability *= 0.9; 745 | } 746 | } 747 | } 748 | if (assertedSuperClassesMap.get(c).contains(d)) { 749 | if (reasoner.getEquivalentClasses(c).contains(d)) { 750 | //LOG.info(" xxxx Cannot overide: "+c+" SubClassOf "+d); 751 | isZeroProbability = true; 752 | jointProbability = 0; 753 | numWithInvalidEquivClass++; 754 | break; 755 | } 756 | 757 | } 758 | if (!reasoner.isSatisfiable(c)) { 759 | //LOG.info("xxxxUNSAT:"+c+" in state: "+s); 760 | isZeroProbability = true; 761 | jointProbability = 0; 762 | numUnsats++; 763 | break; 764 | 765 | } 766 | } 767 | } 768 | if (isZeroProbability) { 769 | continue; 770 | } 771 | 772 | int maxParents = 0; 773 | Map parentCountMap = new HashMap(); 774 | 775 | // test for consistency. 776 | // 777 | // we first merge the current candidate probabilistic axioms 778 | // with the pre-materialized probabilistic axioms 779 | Set candidateCombinationOfNewAxioms = 780 | new HashSet(axiomCombo); 781 | candidateCombinationOfNewAxioms.addAll(additionalLogicalAxioms); 782 | 783 | for (OWLAxiom candidateAxiom : candidateCombinationOfNewAxioms) { 784 | //LOG.info("xxxxCANDIDATE: "+candidateAxiom + " / "+candidateCombinationOfNewAxioms.size()); 785 | if (candidateAxiom instanceof OWLSubClassOfAxiom) { 786 | OWLClass c = (OWLClass) ((OWLSubClassOfAxiom) candidateAxiom).getSubClass(); 787 | OWLClass t = (OWLClass) ((OWLSubClassOfAxiom) candidateAxiom).getSuperClass(); 788 | Set superClasses = reasoner.getSuperClasses(c, false).getFlattened(); 789 | 790 | if (!superClasses.contains(t)) { 791 | LOG.debug("Pr["+candidateAxiom+"]=0 because InferredProperSupers("+c+") DOES NOT CONTAIN "+t+" // InferredProperSupers= "+superClasses); 792 | //LOG.info("XX Pr["+candidateAxiom+"]=0 because InferredProperSupers("+c+") DOES NOT CONTAIN "+t+" // InferredProperSupers= "+superClasses); 793 | isZeroProbability = true; 794 | jointProbability = 0; 795 | numViolatedSubClass++; 796 | break; 797 | } 798 | if (!parentCountMap.containsKey(c)) 799 | parentCountMap.put(c, 1); 800 | else { 801 | int np = parentCountMap.get(c)+1; 802 | parentCountMap.put(c, np); 803 | if (np > maxParents) { 804 | maxParents = np; 805 | } 806 | } 807 | } 808 | else if (candidateAxiom instanceof OWLEquivalentClassesAxiom) { 809 | OWLEquivalentClassesAxiom eax = (OWLEquivalentClassesAxiom)candidateAxiom; 810 | List xs = eax.getClassExpressionsAsList(); 811 | // guaranteed to have 2 812 | Set equivalentClasses = reasoner.getEquivalentClasses(xs.get(0)).getEntities(); 813 | if (!equivalentClasses.contains(xs.get(1))) { 814 | // TODO - check, can this situation ever arise? 815 | //LOG.info("XX FAILED "+xs.get(1)+" NOT IN "+equivalentClasses); 816 | isZeroProbability = true; 817 | jointProbability = 0; 818 | numMissingEquivClass++; 819 | break; 820 | } 821 | } 822 | else { 823 | // annotation axiom 824 | } 825 | } 826 | if (isZeroProbability) { 827 | continue; 828 | } 829 | 830 | // look at distribution of number of parents of leaf nodes. 831 | // for now we have a simplistic model that just looks at the maximum number of 832 | // parents for any leaf node, and penalizes this proportionally 833 | 834 | 835 | double pMaxParents = 0.3; 836 | if (maxParents > 1) { 837 | pMaxParents = 0.4 * (1.0 / Math.pow(2, maxParents-1)); 838 | } 839 | //LOG.info("xxxx MAX_PARENTS:"+maxParents+" p="+pMaxParents+ " jp="+jointProbability+" init="+initialProbability); 840 | //disable 841 | //jointProbability *= pMaxParents; 842 | 843 | jointProbability *= initialProbability; 844 | 845 | LOG.debug(" Prob="+jointProbability+" "+axiomCombo); 846 | stateScoreMap.put(s, jointProbability); 847 | sumOfJointProbabilities += jointProbability; 848 | if (jointProbability > maxJointProbability) { 849 | maxJointProbability = jointProbability; 850 | currentBestCombinationOfAxioms = new HashSet(axiomCombo); 851 | } 852 | numValidCombos++; 853 | } // end of iterating through all combos 854 | 855 | LOG.info("NUM VALID COMBOS:"+numValidCombos+" / "+NUM_STATES); 856 | if (numValidCombos == 0) { 857 | LOG.error("UNSOLVABLE"); 858 | cliqSoln.messages.add("UNSATISFIABLE"); 859 | cliqSoln.solved = false; 860 | cliqSoln.probability = 0.0; 861 | reasoner.dispose(); 862 | return cliqSoln; 863 | } 864 | 865 | sumOfJointProbabilities += (1-initialProbability); 866 | 867 | double finalPr = maxJointProbability / sumOfJointProbabilities; 868 | LOG.info("MAX_JOINT_PR:"+maxJointProbability); 869 | LOG.info("ADJUSTED:"+finalPr); 870 | LOG.info("BEST: "+render(currentBestCombinationOfAxioms)); 871 | cliqSoln.probability = finalPr; 872 | List vals = new ArrayList(stateScoreMap.values()); 873 | //Ordering valueComparator = Ordering.natural().onResultOf(Functions.forMap(stateScoreMap)); 874 | Collections.sort(vals, Collections.reverseOrder()); 875 | if (vals.size() > 0) 876 | LOG.info("BEST/CHECK: "+vals.get(0)); 877 | else 878 | LOG.error("NO COMBINATION"); 879 | //LOG.info("2nd BEST: "+vals.get(1)); 880 | 881 | Set bestCombinationOfAxioms = currentBestCombinationOfAxioms; 882 | if (additionalLogicalAxioms != null) 883 | bestCombinationOfAxioms.addAll(additionalLogicalAxioms); 884 | if (vals.size() > 1) 885 | cliqSoln.confidence = (maxJointProbability / vals.get(1))-1; 886 | else 887 | cliqSoln.confidence = (maxJointProbability /(1-initialProbability))-1; 888 | cliqSoln.axioms = 889 | new HashSet(bestCombinationOfAxioms); 890 | // TODO: annotate axioms 891 | 892 | cliqSoln.axiomStrings = new HashSet(); 893 | for (OWLAxiom ax : bestCombinationOfAxioms) { 894 | cliqSoln.axiomStrings.add(render(ax)); 895 | } 896 | cliqSoln.solved = true; 897 | 898 | // put sub-cliques into clique solution 899 | mgr.removeAxioms(candidateOntology, candidateOntology.getAxioms()); 900 | mgr.addAxioms(candidateOntology, bestCombinationOfAxioms); 901 | reasoner.flush(); 902 | cliqSoln.nodes = new HashSet<>(); 903 | for (OWLClass c : cliqSoln.classes) { 904 | cliqSoln.nodes.add(reasoner.getEquivalentClasses(c)); 905 | } 906 | 907 | for (OWLClass c : n.getEntities()) { 908 | for (OWLClass d : n.getEntities()) { 909 | if (c.equals(d)) 910 | continue; 911 | if (isInSameOntology(c, d)) { 912 | 913 | if (reasoner.getSuperClasses(c, false).containsEntity(d)) { 914 | if (!assertedSuperClassesMap.get(c).contains(d)) { 915 | cliqSoln.messages.add("ENTAILED: "+render(c)+" SubClassOf "+render(d)); 916 | } 917 | } 918 | } 919 | } 920 | } 921 | 922 | // always dispose of our reasoner 923 | reasoner.dispose(); 924 | 925 | return cliqSoln; 926 | } 927 | 928 | /** 929 | * NOTE: some of this code is duplicated from solveClique, 930 | * but it cannot be replaced entirely, see below 931 | * 932 | * @param candidateAxiom 933 | * @param classes 934 | * @param reasoner 935 | * @return 936 | */ 937 | private boolean testForValidity(OWLAxiom candidateAxiom, Set classes, OWLReasoner reasoner) { 938 | if (candidateAxiom == null) { 939 | return true; 940 | } 941 | boolean isValid = true; 942 | for (OWLClass c : classes) { 943 | for (OWLClass d : classes) { 944 | if (c.equals(d)) 945 | continue; 946 | 947 | if (isInSameOntology(c, d)) { 948 | //LOG.info("Same ontology: "+c+" "+d); 949 | if (reasoner.getEquivalentClasses(c).contains(d)) { 950 | //LOG.info(" INVALID: "+c+"=="+d); 951 | isValid = false; 952 | break; 953 | } 954 | } 955 | } 956 | } 957 | if (isValid) { 958 | //LOG.info("CANDIDATE: "+candidateAxiom); 959 | if (candidateAxiom instanceof OWLSubClassOfAxiom) { 960 | OWLClass c = (OWLClass) ((OWLSubClassOfAxiom) candidateAxiom).getSubClass(); 961 | OWLClass t = (OWLClass) ((OWLSubClassOfAxiom) candidateAxiom).getSuperClass(); 962 | Set superClasses = reasoner.getSuperClasses(c, false).getFlattened(); 963 | 964 | if (!superClasses.contains(t)) { 965 | LOG.info("Pr["+candidateAxiom+"]=0 because InferredProperSupers("+c+") DOES NOT CONTAIN "+t+" // InferredProperSupers= "+superClasses); 966 | isValid = false; 967 | } 968 | } 969 | else if (candidateAxiom instanceof OWLEquivalentClassesAxiom) { 970 | OWLEquivalentClassesAxiom eax = (OWLEquivalentClassesAxiom)candidateAxiom; 971 | List xs = eax.getClassExpressionsAsList(); 972 | // guaranteed to have 2 973 | Set equivalentClasses = reasoner.getEquivalentClasses(xs.get(0)).getEntities(); 974 | if (!equivalentClasses.contains(xs.get(1))) { 975 | //LOG.info("XX FAILED "+xs.get(1)+" NOT IN "+equivalentClasses); 976 | isValid = false; 977 | } 978 | } 979 | } 980 | return isValid; 981 | } 982 | 983 | /** 984 | * A subset of probabilistic edges may be entailed; 985 | * 986 | * for example, an OMIM to DOID association may have a 0.75 probability of 987 | * being a SubClassOf 988 | * 989 | * At the same time, the OMIM class may be entailed to be a SubClassOf, 990 | * based on axioms added by a curator (in this case, for MonDO, the axioms 991 | * may come from the omimclusters ontology). 992 | * 993 | * This method will find entailed edges - these can then be used by the calling 994 | * code to alter the probabilistic graph 995 | * 996 | * @param pg 997 | * @param reasoner 998 | * @return Any edges in the PrGraph for which the relationship between (s,t) can be entailed 999 | */ 1000 | public Set findEntailedProbabilisticEdges(ProbabilisticGraph pg, OWLReasoner reasoner) { 1001 | Set rmEdges = new HashSet<>(); 1002 | for (ProbabilisticEdge e : pg.getProbabilisticEdges()) { 1003 | OWLClass s = e.getSourceClass(); 1004 | OWLClass t = e.getTargetClass(); 1005 | if (reasoner.getEquivalentClasses(s).contains(t) || 1006 | reasoner.getSuperClasses(s, false).containsEntity(t) || 1007 | reasoner.getSuperClasses(t, false).containsEntity(s)) { 1008 | rmEdges.add(e); 1009 | } 1010 | } 1011 | return rmEdges; 1012 | } 1013 | 1014 | /** 1015 | * Computes the {@link ProbabilisticGraph.setProbabilityIndex()} 1016 | * 1017 | * NOTE: if the probabilistic edge list changes, this must be recalculated 1018 | * 1019 | * @param probabilisticGraph 1020 | */ 1021 | public void OLDcalculateEdgeProbabilityMatrix(ProbabilisticGraph probabilisticGraph) { 1022 | 1023 | List prEdges = probabilisticGraph.getProbabilisticEdges(); 1024 | int N = prEdges.size(); 1025 | 1026 | // both indices are keyed by the index of the prEdge list; 1027 | // TODO - less dumb way of doing this 1028 | OWLAxiom[][] axiomIndex = new OWLAxiom[N][4]; 1029 | double[][] probabilityIndex = new double[N][4]; 1030 | 1031 | Map axiomPriorProbabilityMap = new HashMap<>(); 1032 | 1033 | OWLDataFactory df = getOWLDataFactory(); 1034 | 1035 | // initialize 1036 | for (int ei = 0; ei < N; ei++) { 1037 | ProbabilisticEdge e = prEdges.get(ei); 1038 | OWLClass sc = e.getSourceClass(); 1039 | OWLClass tc = e.getTargetClass(); 1040 | Map tpm = e.getProbabilityTable().getTypeProbabilityMap(); 1041 | for (int j=0; j<4; j++) { 1042 | OWLAxiom ax; 1043 | Double pr; 1044 | if (j==1) { 1045 | ax = df.getOWLSubClassOfAxiom(sc, tc); 1046 | pr =tpm.get(EdgeType.SUBCLASS_OF); 1047 | } 1048 | else if (j==2) { 1049 | ax = df.getOWLSubClassOfAxiom(tc, sc); 1050 | pr = tpm.get(EdgeType.SUPERCLASS_OF); 1051 | } 1052 | else if (j == 3) { 1053 | ax = df.getOWLEquivalentClassesAxiom(sc, tc); 1054 | pr = tpm.get(EdgeType.EQUIVALENT_TO); 1055 | } 1056 | else { 1057 | OWLAnnotationProperty prop = df.getOWLAnnotationProperty(IRI.create("http://example.org/differentFrom")); 1058 | ax = df.getOWLAnnotationAssertionAxiom(prop, sc.getIRI(), tc.getIRI()); 1059 | //ax = null; 1060 | pr = 1 - (tpm.get(EdgeType.EQUIVALENT_TO) + tpm.get(EdgeType.SUBCLASS_OF) 1061 | + tpm.get(EdgeType.SUPERCLASS_OF)); 1062 | //LOG.info("Ax: "+ax+" Pr="+pr); 1063 | } 1064 | //LOG.info("Pr["+ei+"]["+j+"]="+pr+" // "+ax); 1065 | probabilityIndex[ei][j] = pr; 1066 | axiomIndex[ei][j] = ax; 1067 | axiomPriorProbabilityMap.put(ax, pr); 1068 | if (axiomPriorProbabilityMap.get(ax) != pr) { 1069 | LOG.error("ERROR: "+ax+" ***** "+pr); 1070 | } 1071 | } 1072 | //LOG.info("xxx AxiomIndex: " + axiomIndex); 1073 | } 1074 | probabilisticGraph.setAxiomIndex(axiomIndex); 1075 | probabilisticGraph.setProbabilityIndex(probabilityIndex); 1076 | probabilisticGraph.setAxiomPriorProbabilityMap(axiomPriorProbabilityMap); 1077 | } 1078 | 1079 | /** 1080 | * Extract a probabilistic graph sub-module, given a node (equivalence set) 1081 | * 1082 | * This consists of: 1083 | * 1084 | * - A: SubClassOf, EquivalentClasses and DisjointClasses, extracted as per modularization strategy 1085 | * - H: probabilistic edges that connect any two classes in the module 1086 | * 1087 | * Currently only one modularization strategy is implemented: all classes in signature of axiom 1088 | * must be in the seed node 1089 | * 1090 | * (TODO: experiment with SLME methods) 1091 | * 1092 | * @param n - seed node 1093 | * @return probabilistic graph - collection of logical and weighted candidate axioms 1094 | * @throws OWLOntologyCreationException 1095 | */ 1096 | public ProbabilisticGraph getProbabilisticGraphModule(Node n) throws OWLOntologyCreationException { 1097 | 1098 | Set clzs = n.getEntities(); 1099 | Set edges = new HashSet(); 1100 | Set axioms = new HashSet(); 1101 | 1102 | // extract H-graph module 1103 | // TODO: improve efficiency 1104 | for (ProbabilisticEdge e : probabilisticGraph.getProbabilisticEdges()) { 1105 | if (clzs.contains(e.getSourceClass()) && 1106 | clzs.contains(e.getTargetClass())) { 1107 | edges.add(e); 1108 | } 1109 | } 1110 | 1111 | // EXPERIMENTAL: 1112 | // include full SLME module; this slows down reasoning 1113 | if (false) { 1114 | ModuleType type = ModuleType.BOT; 1115 | 1116 | SyntacticLocalityModuleExtractor extractor = 1117 | new SyntacticLocalityModuleExtractor( 1118 | getOWLOntologyManager(), 1119 | sourceOntology, 1120 | type); 1121 | Set entities = 1122 | clzs.stream().map(x -> x).collect(Collectors.toSet()); 1123 | OWLOntology slmeOntology = getOWLOntologyManager().createOntology( 1124 | extractor.extract(entities), 1125 | IRI.create("http://foo.org")); 1126 | Set extractedAxioms = slmeOntology.getAxioms().stream().filter(x -> x.isLogicalAxiom()).collect(Collectors.toSet()); 1127 | axioms.addAll(extractedAxioms); 1128 | getOWLOntologyManager().removeOntology(slmeOntology); 1129 | LOG.info("SLME: "+extractedAxioms); 1130 | 1131 | } 1132 | 1133 | // extract A-graph module 1134 | for (OWLSubClassOfAxiom ax : sourceOntology.getAxioms(AxiomType.SUBCLASS_OF)) { 1135 | if (clzs.contains(ax.getSubClass()) && 1136 | clzs.contains(ax.getSuperClass())) { 1137 | axioms.add(ax); 1138 | } 1139 | } 1140 | for (OWLDisjointClassesAxiom ax : sourceOntology.getAxioms(AxiomType.DISJOINT_CLASSES)) { 1141 | int numOverlap = 0; 1142 | for ( OWLClassExpression x : ax.getClassExpressions() ) { 1143 | if (clzs.contains(x)) { 1144 | numOverlap++; 1145 | } 1146 | } 1147 | if (numOverlap >= 2) { 1148 | axioms.add(ax); 1149 | LOG.info(" ADDING: "+ax); 1150 | break; 1151 | } 1152 | } 1153 | for (OWLEquivalentClassesAxiom ax : sourceOntology.getAxioms(AxiomType.EQUIVALENT_CLASSES)) { 1154 | for (OWLClassExpression x : ax.getClassExpressions()) { 1155 | if (clzs.contains(x)) { 1156 | axioms.add(ax); 1157 | break; 1158 | } 1159 | } 1160 | } 1161 | ProbabilisticGraph sg = new ProbabilisticGraph(); 1162 | sg.setProbabilisticEdges(new ArrayList(edges)); 1163 | sg.setLogicalEdges(axioms); 1164 | return sg; 1165 | } 1166 | 1167 | public boolean isInSameOntology(OWLClass c, OWLClass d) { 1168 | return getClassPrefix(c).equals(getClassPrefix(d)); 1169 | } 1170 | 1171 | public String getClassPrefix(OWLClass c) { 1172 | String frag = c.getIRI().toString().replace("http://purl.obolibrary.org/obo/", ""); 1173 | return frag.replaceAll("_.*", ""); 1174 | } 1175 | 1176 | // TODO: explore use of probability distribution P( NumOfDirectParents(C) | C in O). 1177 | // What are currently prior probabilities could be conditional, based on this, but 1178 | // it may actually be more challenging to estimate these. 1179 | // alternatively, this could be another source node in the overall network. 1180 | public void getDistributionOfNumberOfSuperclasses() { 1181 | for (OWLClass c : sourceOntology.getClassesInSignature(true)) { 1182 | sourceOntology.getSubClassAxiomsForSubClass(c).size(); 1183 | } 1184 | } 1185 | 1186 | /** 1187 | * Reduce the edge size of the clique by eliminating a single probabilistic edge, 1188 | * by assuming it to be true 1189 | * 1190 | * Uses greedy algorithm: 1191 | * 1192 | * Finds the probabilistic edge E that has a state with the highest probability, and 1193 | * assumes it is true (regardless of how this effects the joint probability), 1194 | * translating E from a probabilistic edge to a logical edge. 1195 | * 1196 | * If E is invalid it is added to the unsatisfiable list, and the next best one 1197 | * is chosen 1198 | * 1199 | * @param sg 1200 | * @param addedLogicalAxioms - accumulates all logical axioms added 1201 | * @param reasoner 1202 | * @param unsatisfiableAxioms - accumulates all unsatisfiable axioms 1203 | * @return Pr[reducedState] 1204 | */ 1205 | public Double reduceClique(ProbabilisticGraph sg, Set addedLogicalAxioms, OWLReasoner reasoner, 1206 | Set unsatisfiableAxioms, int recursionDepth) { 1207 | LOG.info("Reducing clique, depth="+recursionDepth+", Unsat:"+render(unsatisfiableAxioms)); 1208 | Double pr = 1.0; 1209 | List newEdges = new ArrayList(); 1210 | int maxi = -1; 1211 | double maxp = 0.0; 1212 | OWLAxiom bestAxiom = null; 1213 | //LOG.info("FINDING BEST AXIOM FROM : "+sg.getProbabilisticEdges().size()); 1214 | for (int i=0; i maxp) { 1219 | OWLAxiom candidateAxiom = sg.getAxiomIndex()[i][j]; 1220 | //LOG.info("Testing if "+candidateAxiom +" in "+unsatisfiableAxioms.size()); 1221 | if (!unsatisfiableAxioms.contains(candidateAxiom)) { 1222 | //LOG.info(" BEST SO FAR: "+candidateAxiom); 1223 | maxp = prt[j]; 1224 | maxi = i; 1225 | bestAxiom = candidateAxiom; 1226 | } 1227 | else { 1228 | //LOG.info("DISCOUNTING!"); 1229 | } 1230 | } 1231 | } 1232 | } 1233 | if (maxi == -1) { 1234 | LOG.info("Greedy algorithm leads to unsatisfiable state"); 1235 | return 0.0; 1236 | } 1237 | 1238 | if (bestAxiom == null) { 1239 | // bestAxiom can be null under two circumstances: 1240 | // 1. the next most likely edge probability is for the 00 case between two classes 1241 | // 2. there are no possibilities that lead to a coherent ontology. 1242 | // 1243 | // in the case of the former, the candidate ontology does not change, 1244 | // so we do not need to run additional validity tests; 1245 | // we account for the second case above (maxi==-1) 1246 | 1247 | } 1248 | else { 1249 | 1250 | // add most likely candidate axiom to ontology 1251 | OWLOntology ont = reasoner.getRootOntology(); 1252 | ont.getOWLOntologyManager().addAxiom(ont, bestAxiom); 1253 | reasoner.flush(); 1254 | 1255 | boolean isValid = testForValidity(bestAxiom, ont.getClassesInSignature(), reasoner); 1256 | if (isValid) { 1257 | for (OWLAxiom ax : addedLogicalAxioms) { 1258 | isValid = testForValidity(ax, ont.getClassesInSignature(), reasoner); 1259 | if (!isValid) { 1260 | break; 1261 | } 1262 | } 1263 | } 1264 | if (!isValid) { 1265 | LOG.info("Eliminating invalid axiom: "+render(bestAxiom)+ " Pr="+maxp); 1266 | unsatisfiableAxioms.add(bestAxiom); 1267 | ont.getOWLOntologyManager().removeAxiom(ont, bestAxiom); 1268 | // recursion; call depth limited by number of axioms 1269 | return reduceClique(sg, addedLogicalAxioms, reasoner, 1270 | unsatisfiableAxioms, recursionDepth+1); 1271 | } 1272 | } 1273 | 1274 | pr *= maxp; 1275 | if (bestAxiom != null) { 1276 | addedLogicalAxioms.add(bestAxiom); 1277 | } 1278 | ProbabilisticEdge e = sg.getProbabilisticEdges().get(maxi); 1279 | newEdges.add(e); 1280 | LOG.info("Translating Probabilistic Edge: " + e + " ==> LOGICAL EDGE: "+render(bestAxiom)+" p="+maxp); 1281 | if (bestAxiom != null) { 1282 | sg.getLogicalEdges().add(bestAxiom); // translate the probabilistic edge to a logical edge 1283 | sg.getProbabilisticEdgeReplacementMap().put(bestAxiom, e); 1284 | Set rmEdges = findEntailedProbabilisticEdges(sg, reasoner); 1285 | rmEdges.remove(e); // will already be removed 1286 | if (rmEdges.size() >0) { 1287 | LOG.info(" Eliminating entailed edges: "+rmEdges); 1288 | // TODO: get join probability of all axioms 1289 | if (isExperimental) { 1290 | LOG.error("TODO: calc probability"); 1291 | sg.getProbabilisticEdges().removeAll(rmEdges); 1292 | } 1293 | } 1294 | } 1295 | else { 1296 | sg.getEliminatedEdges().add(e); 1297 | } 1298 | sg.getProbabilisticEdges().remove(e); 1299 | return pr; 1300 | } 1301 | 1302 | public String render(ProbabilisticEdge e) { 1303 | return renderer.render(e.getSourceClass()) +" -> "+renderer.render(e.getTargetClass()) + 1304 | " PT: "+e.getProbabilityTable(); 1305 | } 1306 | 1307 | public String render(OWLObject obj) { 1308 | if (obj == null) 1309 | return "NULL"; 1310 | return renderer.render(obj); 1311 | } 1312 | 1313 | public String render(Set objs) { 1314 | return objs.stream().map(obj -> render(obj)).collect(Collectors.joining(", ")); 1315 | } 1316 | 1317 | } 1318 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/compute/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Engines to compute over probabilistic graphs 3 | */ 4 | /** 5 | * @author cjm 6 | * 7 | */ 8 | package org.monarchinitiative.boom.compute; -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/io/CliqueSolutionDotWriter.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.io; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.List; 6 | import java.util.Map; 7 | import java.util.Set; 8 | import java.util.stream.Collectors; 9 | 10 | import org.apache.commons.io.FileUtils; 11 | import org.apache.log4j.Logger; 12 | import org.monarchinitiative.boom.model.CliqueSolution; 13 | import org.monarchinitiative.boom.model.EdgeType; 14 | import org.monarchinitiative.boom.model.LabelUtil; 15 | import org.monarchinitiative.boom.model.ProbabilisticEdge; 16 | import org.monarchinitiative.boom.model.ProbabilisticGraph; 17 | import org.semanticweb.owlapi.model.IRI; 18 | import org.semanticweb.owlapi.model.OWLAxiom; 19 | import org.semanticweb.owlapi.model.OWLClass; 20 | import org.semanticweb.owlapi.model.OWLClassExpression; 21 | import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom; 22 | import org.semanticweb.owlapi.model.OWLOntology; 23 | import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; 24 | import org.semanticweb.owlapi.reasoner.Node; 25 | 26 | /** 27 | * Write a clique as a dot file 28 | * 29 | * @author cjm 30 | * 31 | */ 32 | public class CliqueSolutionDotWriter { 33 | 34 | private static Logger LOG = Logger.getLogger(CliqueSolutionDotWriter.class); 35 | private CliqueSolution cs; 36 | private OWLOntology ontology; 37 | private ProbabilisticGraph probabilisticGraph; 38 | 39 | 40 | public CliqueSolutionDotWriter(CliqueSolution cs, OWLOntology ontology) { 41 | super(); 42 | this.cs = cs; 43 | this.ontology = ontology; 44 | } 45 | 46 | 47 | 48 | public CliqueSolutionDotWriter(CliqueSolution cs, OWLOntology ontology, 49 | ProbabilisticGraph probabilisticGraph) { 50 | super(); 51 | this.cs = cs; 52 | this.ontology = ontology; 53 | this.probabilisticGraph = probabilisticGraph; 54 | } 55 | 56 | 57 | 58 | public String render() { 59 | return "digraph cliquegraph {\n" + renderNodesInCliques() + 60 | renderGivenLogicalEdges() + 61 | renderPriorEdges() + 62 | renderFinalAxioms() + 63 | renderReplacedEdges() + 64 | "}"; 65 | } 66 | 67 | public String renderToFile(String dirname) throws IOException { 68 | String base = dirname + getId(cs.cliqueId); 69 | String fn = base + ".dot"; 70 | String png = base + ".png"; 71 | 72 | File f = new File(fn); 73 | FileUtils.writeStringToFile(f, render()); 74 | // TODO - make path configurable 75 | Runtime.getRuntime().exec("/opt/local/bin/dot -Grankdir=BT -T png " + " -o " + png + " " + fn); 76 | return png; 77 | } 78 | 79 | private String renderNodesInCliques() { 80 | if (cs.nodes.size() == 0) { 81 | return cs.classes.stream().map( c -> renderClass(c) ).collect(Collectors.joining("\n")); 82 | 83 | } 84 | else { 85 | return cs.nodes.stream().map( (Node n) -> renderNode(n) ).collect(Collectors.joining("\n")); 86 | } 87 | } 88 | 89 | private String renderNode(Node n) { 90 | return "subgraph cluster_"+getId(n.getRepresentativeElement()) +" {" + 91 | n.getEntities().stream().map( (OWLClass c) -> renderClass(c)).collect(Collectors.joining("\n")) + 92 | "}\n"; 93 | 94 | } 95 | 96 | 97 | private String renderClass(OWLClass c) { 98 | return getId(c) + " [ label=\"" + getLabel(c) + "\" ];"; 99 | } 100 | 101 | private String renderFinalAxioms() { 102 | // render axioms blue 103 | return cs.axioms.stream().map( (OWLAxiom a) -> renderEdge(a, "blue")).collect(Collectors.joining("\n")); 104 | } 105 | private String renderGivenLogicalEdges() { 106 | // note that the greedy optimization procedure will have switched some 107 | // probabilistic edges to logical edges in advance; these will not have an entry in 108 | // the axiom probability index. TODO: improve datamodel so this is not necessary 109 | return cs.subGraph.getLogicalEdges().stream(). 110 | filter( (OWLAxiom a) -> probabilisticGraph.getAxiomPriorProbability(a) == null). 111 | map( (OWLAxiom a) -> renderEdge(a, "black")).collect(Collectors.joining("\n")); 112 | } 113 | 114 | private String renderPriorEdges() { 115 | return cs.subGraph.getProbabilisticEdges().stream().map( (ProbabilisticEdge e) -> renderEdge(e)).collect(Collectors.joining("\n")); 116 | } 117 | 118 | private String renderReplacedEdges() { 119 | Map m = cs.subGraph.getProbabilisticEdgeReplacementMap(); 120 | return m.keySet().stream().map( (OWLAxiom a) -> renderEdge(a, "pink")).collect(Collectors.joining("\n")) + 121 | m.values().stream().map( e -> renderEdge(e, "green")).collect(Collectors.joining("\n")) + 122 | renderProbabilisticEdges(cs.subGraph.getEliminatedEdges(), "pink"); 123 | } 124 | 125 | private String renderProbabilisticEdges(Set edges, String color) { 126 | return edges.stream().map( (ProbabilisticEdge e) -> renderEdge(e, color)).collect(Collectors.joining("\n")); 127 | } 128 | 129 | 130 | private String pct(Double n) { 131 | Integer i = (int) (n * 100.0); 132 | return i.toString(); 133 | } 134 | private String renderEdge(ProbabilisticEdge e) { 135 | return renderEdge(e, "blue"); 136 | } 137 | private String renderEdge(ProbabilisticEdge e, String color) { 138 | Map tm = e.getProbabilityTable().getTypeProbabilityMap(); 139 | 140 | String plabel = ""; 141 | if (!cs.solved) { 142 | // showing the prior probability for each state clutters the display; 143 | // only do this when there is no solution. 144 | // if there is a solution, then one of the states will have been selected, 145 | // and the prior probability for this will already be shown (via 146 | // renderEdge(OWLAxiom x)) 147 | plabel = 148 | "("+pct(tm.get(EdgeType.SUBCLASS_OF)) + "-" + 149 | pct(tm.get(EdgeType.SUPERCLASS_OF)) + "-" + 150 | pct(tm.get(EdgeType.EQUIVALENT_TO)) + ")"; 151 | } 152 | // probabilistic edges are dotted 153 | return renderEdge( 154 | getId(getId(e.getSourceClass())), 155 | getId(getId(e.getTargetClass())), 156 | "none", 157 | "dotted", 158 | color, 159 | 1, 160 | plabel, 161 | ""); // TODO 162 | } 163 | 164 | private String renderEdge(OWLAxiom ax, String color) { 165 | String elabel; 166 | Double pr = probabilisticGraph.getAxiomPriorProbability(ax); 167 | int penwidth; 168 | if (pr == null) { 169 | elabel = ""; 170 | penwidth = 1; 171 | } 172 | else { 173 | elabel = pct(pr); 174 | penwidth = (int) (1 + pr*10); 175 | if (cs.subGraph.getLogicalEdges().contains(ax)) { 176 | // the probabilistic edge was turned into a logical edge 177 | // by the greedy optimization algorithm 178 | elabel = elabel + "*"; 179 | } 180 | } 181 | if (ax instanceof OWLSubClassOfAxiom) { 182 | OWLSubClassOfAxiom sca = (OWLSubClassOfAxiom)ax; 183 | return renderEdge( 184 | getId((OWLClass) sca.getSubClass()), 185 | getId((OWLClass) sca.getSuperClass()), 186 | "normal", 187 | "solid", 188 | color, 189 | penwidth, 190 | elabel, 191 | ""); 192 | } 193 | else if (ax instanceof OWLEquivalentClassesAxiom) { 194 | OWLEquivalentClassesAxiom eca = (OWLEquivalentClassesAxiom)ax; 195 | List xs = eca.getClassExpressionsAsList(); 196 | if (xs.size() == 2) { 197 | OWLClassExpression subc = xs.get(0); 198 | OWLClassExpression supc = xs.get(1); 199 | if (!subc.isAnonymous() && 200 | !supc.isAnonymous()) { 201 | return renderEdge( 202 | getId((OWLClass) subc), 203 | getId((OWLClass) supc), 204 | "ediamond", 205 | "solid", 206 | "red", 207 | penwidth, 208 | elabel, 209 | ", arrowtail=ediamond, dir=both"); 210 | } 211 | } 212 | else { 213 | LOG.warn("I currently only handle equivalance with arity=2: "+xs); 214 | return null; 215 | } 216 | } 217 | return null; 218 | } 219 | 220 | private String renderEdge(String s, String t, String arrowhead, 221 | String style, String color, Integer penwidth, String elabel, String extra) { 222 | 223 | return s + " -> " + t +" [ arrowhead = " + arrowhead +", penwidth="+penwidth+ 224 | ", color="+color+", label=\""+elabel+"\""+ 225 | ", style="+style+extra+"]\n"; 226 | } 227 | 228 | 229 | private String getId(OWLClass c) { 230 | return c.getIRI().getFragment().replace(".", "_").replace("-", "_"); 231 | } 232 | 233 | private String getId(String c) { 234 | return IRI.create(c).getFragment(); 235 | } 236 | 237 | 238 | private String getLabel(OWLClass c) { 239 | String label = LabelUtil.getLabel(c, ontology); 240 | label = label.replaceAll(" ", "\n"); 241 | label = label.replaceAll("\"", "'"); 242 | return c.getIRI().getFragment() + " " + label; 243 | } 244 | 245 | } 246 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/io/IDTools.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.io; 2 | 3 | import org.semanticweb.owlapi.model.IRI; 4 | 5 | public class IDTools { 6 | 7 | public static IRI getIRIByIdentifier(String id) { 8 | // TODO - use JSON-LD library and context 9 | if (id.startsWith("http")) { 10 | return IRI.create(id); 11 | } 12 | else { 13 | return IRI.create("http://purl.obolibrary.org/obo/"+id.replace(":", "_")); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/io/LabelProvider.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.io; 2 | 3 | import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; 4 | import org.semanticweb.owlapi.model.OWLAnnotationValue; 5 | import org.semanticweb.owlapi.model.OWLEntity; 6 | import org.semanticweb.owlapi.model.OWLLiteral; 7 | import org.semanticweb.owlapi.model.OWLOntology; 8 | import org.semanticweb.owlapi.util.ShortFormProvider; 9 | 10 | public class LabelProvider implements ShortFormProvider { 11 | 12 | OWLOntology ontology; 13 | boolean hideIds = false; 14 | boolean quoteLabels = true; 15 | 16 | 17 | public LabelProvider(OWLOntology ont) { 18 | super(); 19 | this.ontology = ont; 20 | } 21 | 22 | 23 | public String getShortForm(OWLEntity entity) { 24 | String label = getLabel(entity); 25 | if (label == null) { 26 | return getTruncatedId(entity); 27 | } 28 | else { 29 | if (hideIds) { 30 | return label; 31 | } 32 | return getTruncatedId(entity) + " "+ label; 33 | } 34 | } 35 | 36 | public String getLabel(OWLEntity entity) { 37 | 38 | for (OWLAnnotationAssertionAxiom a : ontology.getAnnotationAssertionAxioms(entity.getIRI())) { 39 | if (a.getProperty().isLabel()) { 40 | OWLAnnotationValue v = a.getValue(); 41 | if (v instanceof OWLLiteral) { 42 | return ((OWLLiteral)v).getLiteral(); 43 | } 44 | } 45 | } 46 | return null; 47 | } 48 | 49 | public String getTruncatedId(OWLEntity entity) { 50 | return entity.getIRI().getFragment(); 51 | } 52 | 53 | 54 | @Override 55 | public void dispose() { 56 | // TODO Auto-generated method stub 57 | 58 | } 59 | 60 | 61 | 62 | } -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/io/Loader.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.io; 2 | 3 | import org.monarchinitiative.boom.compute.ProbabilisticGraphCalculator; 4 | 5 | public class Loader { 6 | 7 | public ProbabilisticGraphCalculator load(String ontFilePath, String f) { 8 | OWLLoader loader = new OWLLoader(); 9 | return null; 10 | 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/io/OWLLoader.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.io; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | 6 | import org.apache.log4j.Logger; 7 | import org.monarchinitiative.boom.compute.ProbabilisticGraphCalculator; 8 | import org.monarchinitiative.boom.model.ProbabilisticGraph; 9 | import org.semanticweb.owlapi.apibinding.OWLManager; 10 | import org.semanticweb.owlapi.model.IRI; 11 | import org.semanticweb.owlapi.model.OWLOntology; 12 | import org.semanticweb.owlapi.model.OWLOntologyCreationException; 13 | import org.semanticweb.owlapi.model.OWLOntologyManager; 14 | 15 | import com.google.common.base.Preconditions; 16 | 17 | /** 18 | * Object for loading OWL ontologies into a {@link BMKnowledgeBase} 19 | * 20 | * Note that a KB consists of classes and individuals, both of which can be loaded 21 | * from an ontology 22 | * 23 | * @author cjm 24 | * 25 | */ 26 | public class OWLLoader { 27 | private Logger LOG = Logger.getLogger(OWLLoader.class); 28 | 29 | OWLOntologyManager manager; 30 | OWLOntology owlOntology; 31 | 32 | /** 33 | * @param iri 34 | * @return OWL Ontology 35 | * @throws OWLOntologyCreationException 36 | */ 37 | public OWLOntology loadOWL(IRI iri) throws OWLOntologyCreationException { 38 | return getOWLOntologyManager().loadOntology(iri); 39 | } 40 | 41 | /** 42 | * @param file 43 | * @return OWL Ontology 44 | * @throws OWLOntologyCreationException 45 | */ 46 | public OWLOntology loadOWL(File file) throws OWLOntologyCreationException { 47 | IRI iri = IRI.create(file); 48 | return getOWLOntologyManager().loadOntologyFromOntologyDocument(iri); 49 | } 50 | 51 | /** 52 | * Loads an OWL ontology from a URI or file 53 | * 54 | * @param path 55 | * @return OWL Ontology 56 | * @throws OWLOntologyCreationException 57 | */ 58 | public OWLOntology loadOWL(String path) throws OWLOntologyCreationException { 59 | if (path.startsWith("http")) { 60 | return loadOWL(IRI.create(path)); 61 | } 62 | else { 63 | File file = new File(path); 64 | return loadOWL(file); 65 | } 66 | } 67 | 68 | /** 69 | * @param iri 70 | * @throws OWLOntologyCreationException 71 | */ 72 | public void load(IRI iri) throws OWLOntologyCreationException { 73 | owlOntology = getOWLOntologyManager().loadOntology(iri); 74 | Preconditions.checkNotNull(owlOntology); 75 | } 76 | 77 | /** 78 | * @param file 79 | * @throws OWLOntologyCreationException 80 | */ 81 | public void load(File file) throws OWLOntologyCreationException { 82 | owlOntology = loadOWL(file); 83 | Preconditions.checkNotNull(owlOntology); 84 | } 85 | 86 | 87 | 88 | /** 89 | * Loads an OWL ontology from a URI or file 90 | * 91 | * @param path 92 | * @throws OWLOntologyCreationException 93 | */ 94 | public OWLOntology load(String path) throws OWLOntologyCreationException { 95 | owlOntology = loadOWL(path); 96 | Preconditions.checkNotNull(owlOntology); 97 | return owlOntology; 98 | } 99 | 100 | 101 | public OWLOntologyManager getOWLOntologyManager() { 102 | if (manager == null) 103 | manager = OWLManager.createOWLOntologyManager(); 104 | return manager; 105 | } 106 | 107 | public ProbabilisticGraphCalculator createProbabilisticGraphCalculator(String ontFile, 108 | String ptablePath) throws OWLOntologyCreationException, IOException { 109 | owlOntology = loadOWL(ontFile); 110 | ProbabilisticGraphParser parser = 111 | new ProbabilisticGraphParser(owlOntology); 112 | ProbabilisticGraph pg = 113 | parser.parse(ptablePath); 114 | ProbabilisticGraphCalculator pgc = new ProbabilisticGraphCalculator(owlOntology, pg); 115 | return pgc; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/io/ProbabilisticGraphParser.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.io; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.List; 6 | 7 | import org.apache.commons.io.FileUtils; 8 | import org.apache.log4j.Logger; 9 | import org.monarchinitiative.boom.model.ProbabilisticEdge; 10 | import org.monarchinitiative.boom.model.ProbabilisticGraph; 11 | import org.semanticweb.owlapi.model.IRI; 12 | import org.semanticweb.owlapi.model.OWLClass; 13 | import org.semanticweb.owlapi.model.OWLDataFactory; 14 | import org.semanticweb.owlapi.model.OWLOntology; 15 | 16 | /** 17 | * Parses probability tables 18 | * 19 | * Format: 20 | * 21 | * ClassA ClassB Pr(ASubClassOfB) Pr(BSubClassOfA) Pr(AEquivalentToB) Pr(ANotInLineageWithB) 22 | * 23 | * 24 | * Note that here SubClassOf denotes both proper (ie not equivalent) and entailed/ancestors 25 | * 26 | * 27 | * 28 | * @author cjm 29 | * 30 | */ 31 | public class ProbabilisticGraphParser { 32 | 33 | private static Logger LOG = Logger.getLogger(ProbabilisticGraphParser.class); 34 | private OWLOntology ontology; 35 | 36 | public ProbabilisticGraphParser(OWLOntology ontology) { 37 | super(); 38 | this.ontology = ontology; 39 | } 40 | 41 | public ProbabilisticGraph parse(String fn) throws IOException { 42 | File file = new File(fn); 43 | return parse(file); 44 | } 45 | 46 | public ProbabilisticGraph parse(File file) throws IOException { 47 | ProbabilisticGraph pg = new ProbabilisticGraph(); 48 | List lines = FileUtils.readLines(file, "UTF-8"); 49 | OWLDataFactory df = ontology.getOWLOntologyManager().getOWLDataFactory(); 50 | for (String line : lines) { 51 | String[] vs = line.split("\\t"); 52 | IRI siri = IDTools.getIRIByIdentifier(vs[0]); 53 | IRI tiri = IDTools.getIRIByIdentifier(vs[1]); 54 | OWLClass s = df.getOWLClass(siri); 55 | OWLClass t = df.getOWLClass(tiri); 56 | 57 | if (s == null || t == null) { 58 | LOG.error("MISSING: "+line+" S="+s+" T="+t); 59 | continue; 60 | } 61 | ProbabilisticEdge e = new ProbabilisticEdge(s, t, 62 | Double.parseDouble(vs[2]), 63 | Double.parseDouble(vs[3]), 64 | Double.parseDouble(vs[4]), 65 | Double.parseDouble(vs[5])); 66 | pg.getProbabilisticEdges().add(e); 67 | 68 | } 69 | pg.collapseReciprocals(); 70 | return pg; 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/io/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Reading and writing of probabilstic graphs. 3 | * 4 | * There are two formats: OWL, and probabilistic edge tables 5 | */ 6 | /** 7 | * @author cjm 8 | * 9 | */ 10 | package org.monarchinitiative.boom.io; -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/model/CliqueSolution.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | import org.semanticweb.owlapi.model.OWLAxiom; 9 | import org.semanticweb.owlapi.model.OWLClass; 10 | import org.semanticweb.owlapi.reasoner.Node; 11 | 12 | import com.google.gson.annotations.Expose; 13 | 14 | /** 15 | * A set of consistent axioms that can break a clique, and is considered the most 16 | * likely based on a set of prior probabilities 17 | * 18 | * @author cjm 19 | * 20 | */ 21 | public class CliqueSolution { 22 | 23 | @Expose public String cliqueId; 24 | @Expose public Set members; 25 | @Expose public int size; 26 | @Expose public int initialNumberOfProbabilisticEdges; 27 | @Expose public Double probability; 28 | @Expose public Double minProbability; 29 | @Expose public Double confidence; 30 | @Expose public Boolean solved; 31 | @Expose public List messages = new ArrayList(); 32 | @Expose public List selections = new ArrayList(); 33 | @Expose public long timeToSolve; 34 | 35 | public Set classes = new HashSet<>(); 36 | public Set axioms = new HashSet<>(); 37 | public ProbabilisticGraph subGraph; 38 | public Set> nodes = new HashSet<>(); 39 | 40 | @Expose public Set axiomStrings; 41 | 42 | /* (non-Javadoc) 43 | * @see java.lang.Object#toString() 44 | */ 45 | @Override 46 | public String toString() { 47 | return "CliqueReport [cliqueId=" + cliqueId + ", members=" + members 48 | + ", probability=" + probability + ", confidence=" + confidence 49 | + ", axioms=" + axioms + "]"; 50 | } 51 | 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/model/EdgeProbabilityTable.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.model; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class EdgeProbabilityTable { 7 | 8 | private Map typeProbabilityMap; 9 | 10 | public EdgeProbabilityTable(double pSUB, double pSUP, double pEQ, double pNULL) { 11 | super(); 12 | setTypeProbabilityMap(new HashMap()); 13 | getTypeProbabilityMap().put(EdgeType.SUBCLASS_OF, pSUB); 14 | getTypeProbabilityMap().put(EdgeType.SUPERCLASS_OF, pSUP); 15 | getTypeProbabilityMap().put(EdgeType.EQUIVALENT_TO, pEQ); 16 | getTypeProbabilityMap().put(EdgeType.NONE, pNULL); 17 | } 18 | 19 | public Map getTypeProbabilityMap() { 20 | return typeProbabilityMap; 21 | } 22 | 23 | public void setTypeProbabilityMap(Map typeProbabilityMap) { 24 | this.typeProbabilityMap = typeProbabilityMap; 25 | } 26 | 27 | /* (non-Javadoc) 28 | * @see java.lang.Object#toString() 29 | */ 30 | @Override 31 | public String toString() { 32 | Map tpm = getTypeProbabilityMap(); 33 | return 34 | " Sub: " + tpm.get(EdgeType.SUBCLASS_OF) + 35 | " Sup: " + tpm.get(EdgeType.SUPERCLASS_OF) + 36 | " Eqv: " + tpm.get(EdgeType.EQUIVALENT_TO) + 37 | " N/a: " + tpm.get(EdgeType.NONE) + 38 | "]"; 39 | } 40 | 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/model/EdgeType.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.model; 2 | 3 | public enum EdgeType { 4 | SUBCLASS_OF, SUPERCLASS_OF, EQUIVALENT_TO, NONE 5 | } -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/model/LabelUtil.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.model; 2 | 3 | import java.util.Collection; 4 | import java.util.List; 5 | 6 | import org.monarchinitiative.boom.io.LabelProvider; 7 | import org.semanticweb.owlapi.model.OWLAnnotation; 8 | import org.semanticweb.owlapi.model.OWLAnnotationProperty; 9 | import org.semanticweb.owlapi.model.OWLAxiom; 10 | import org.semanticweb.owlapi.model.OWLClass; 11 | import org.semanticweb.owlapi.model.OWLClassExpression; 12 | import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom; 13 | import org.semanticweb.owlapi.model.OWLLiteral; 14 | import org.semanticweb.owlapi.model.OWLOntology; 15 | import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; 16 | import org.semanticweb.owlapi.search.EntitySearcher; 17 | import org.semanticweb.owlapi.vocab.OWLRDFVocabulary; 18 | 19 | /** 20 | * TODO - switch to using {@link LabelProvider} 21 | * 22 | * @author cjm 23 | * 24 | */ 25 | public class LabelUtil { 26 | 27 | public static String render(OWLAxiom axiom, OWLOntology ontology) { 28 | if (axiom instanceof OWLSubClassOfAxiom) { 29 | OWLSubClassOfAxiom sca = (OWLSubClassOfAxiom)axiom; 30 | return getIdLabel((OWLClass) sca.getSubClass(), ontology) + " < " + 31 | getIdLabel((OWLClass) sca.getSuperClass(), ontology); 32 | } 33 | else if (axiom instanceof OWLEquivalentClassesAxiom) { 34 | List xs = ((OWLEquivalentClassesAxiom)axiom).getClassExpressionsAsList(); 35 | return getIdLabel((OWLClass) xs.get(0), ontology) + " == " + 36 | getIdLabel((OWLClass) xs.get(1), ontology); 37 | } 38 | else { 39 | return axiom.toString(); 40 | } 41 | } 42 | 43 | public static String getIdLabel(OWLClass c, OWLOntology ontology) { 44 | return c.getIRI().getFragment() + " " + getLabel(c, ontology); 45 | } 46 | 47 | public static String getLabel(OWLClass c, OWLOntology ontology) { 48 | OWLAnnotationProperty p = ontology.getOWLOntologyManager().getOWLDataFactory().getRDFSLabel(); 49 | Collection anns = EntitySearcher.getAnnotations(c, ontology); 50 | for (OWLAnnotation a : anns) { 51 | if (a.getValue() instanceof OWLLiteral && a.getProperty().equals(p)) { 52 | return ((OWLLiteral)a.getValue()).getLiteral().toString(); 53 | } 54 | } 55 | return ""; 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/model/ProbabilisticEdge.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.model; 2 | 3 | import org.semanticweb.owlapi.model.OWLClass; 4 | 5 | public class ProbabilisticEdge { 6 | 7 | final OWLClass sourceClass; 8 | final OWLClass targetClass; 9 | final EdgeProbabilityTable probabilityTable; 10 | 11 | 12 | 13 | public ProbabilisticEdge(OWLClass sourceClass, OWLClass targetClass, 14 | EdgeProbabilityTable probabilityTable) { 15 | super(); 16 | this.sourceClass = sourceClass; 17 | this.targetClass = targetClass; 18 | this.probabilityTable = probabilityTable; 19 | } 20 | 21 | public ProbabilisticEdge(OWLClass s, OWLClass t, double pSUB, double pSUP, double pEQ, double pNULL) { 22 | super(); 23 | this.sourceClass = s; 24 | this.targetClass = t; 25 | probabilityTable = new EdgeProbabilityTable(pSUB, pSUP, pEQ, pNULL); 26 | 27 | } 28 | 29 | /** 30 | * @return the sourceClass 31 | */ 32 | public OWLClass getSourceClass() { 33 | return sourceClass; 34 | } 35 | 36 | /** 37 | * @return the targetClass 38 | */ 39 | public OWLClass getTargetClass() { 40 | return targetClass; 41 | } 42 | 43 | /** 44 | * @return the probabilityTable 45 | */ 46 | public EdgeProbabilityTable getProbabilityTable() { 47 | return probabilityTable; 48 | } 49 | 50 | /* (non-Javadoc) 51 | * @see java.lang.Object#toString() 52 | */ 53 | @Override 54 | public String toString() { 55 | return sourceClass 56 | + " -> " + targetClass + " Pr[" 57 | + probabilityTable + "]"; 58 | } 59 | 60 | 61 | 62 | 63 | 64 | 65 | } 66 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/model/ProbabilisticGraph.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Set; 9 | 10 | import org.apache.log4j.Logger; 11 | import org.semanticweb.owlapi.model.IRI; 12 | import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; 13 | import org.semanticweb.owlapi.model.OWLAnnotationProperty; 14 | import org.semanticweb.owlapi.model.OWLAxiom; 15 | import org.semanticweb.owlapi.model.OWLClass; 16 | import org.semanticweb.owlapi.model.OWLDataFactory; 17 | import org.semanticweb.owlapi.model.OWLOntology; 18 | import org.semanticweb.owlapi.model.OWLOntologyCreationException; 19 | import org.semanticweb.owlapi.model.OWLOntologyManager; 20 | 21 | /** 22 | * A probabilistic graph/ontology consists of logical axioms and probabilistic axioms. 23 | * 24 | * Here, probabilistic axioms are limited to {@link ProbabilisticEdge}s. 25 | * 26 | * A PG can be used either for the set of all probabilistic logical relationships 27 | * in an ontology, or for a subgraph. 28 | * 29 | * @author cjm 30 | * 31 | */ 32 | public class ProbabilisticGraph { 33 | 34 | private static Logger LOG = Logger.getLogger(ProbabilisticGraph.class); 35 | 36 | public static IRI DIFFERENT_FROM = IRI.create("http://example.org/differentFrom"); 37 | 38 | List probabilisticEdges = new ArrayList(); 39 | Set logicalEdges = new HashSet(); 40 | 41 | private OWLAxiom[][] axiomIndex; 42 | private double[][] probabilityIndex; 43 | private Map axiomPriorProbabilityMap = new HashMap<>(); 44 | private Map probabilisticEdgeReplacementMap = new HashMap<>(); 45 | private Set eliminatedEdges = new HashSet<>(); 46 | 47 | /** 48 | * Note the edge lists is mutable; if it changes, axiomIndex must be recalculated 49 | * 50 | * @return the edges 51 | */ 52 | public List getProbabilisticEdges() { 53 | return probabilisticEdges; 54 | } 55 | 56 | 57 | /** 58 | * @param edges the edges to add 59 | */ 60 | public void setProbabilisticEdges(List edges) { 61 | this.probabilisticEdges = edges; 62 | } 63 | 64 | /** 65 | * @param badEdges the edges to remove 66 | */ 67 | public void removeEdges(Set badEdges) { 68 | this.probabilisticEdges.removeAll(badEdges); 69 | } 70 | 71 | 72 | /** 73 | * @return the logicalEdges 74 | */ 75 | public Set getLogicalEdges() { 76 | return logicalEdges; 77 | } 78 | 79 | /** 80 | * @param logicalEdges the logicalEdges to set 81 | */ 82 | public void setLogicalEdges(Set logicalEdges) { 83 | this.logicalEdges = logicalEdges; 84 | } 85 | 86 | /** 87 | * @param logicalEdges the logicalEdges to set 88 | */ 89 | public void addLogicalEdges(Set logicalEdges) { 90 | this.logicalEdges.addAll(logicalEdges); 91 | } 92 | 93 | 94 | /** 95 | * TODO: use immutable lists for edges; this index must be recalculated if edges change 96 | * 97 | * @return logical axiom index keyed by edge index and type 98 | */ 99 | public OWLAxiom[][] getAxiomIndex() { 100 | return axiomIndex; 101 | } 102 | 103 | 104 | public void setAxiomIndex(OWLAxiom[][] axiomIndex) { 105 | this.axiomIndex = axiomIndex; 106 | } 107 | 108 | 109 | /** 110 | * TODO: use immutable lists for edges; this index must be recalculated if edges change 111 | * 112 | * @return pr index keyed by edge index and type 113 | */ 114 | public double[][] getProbabilityIndex() { 115 | return probabilityIndex; 116 | } 117 | 118 | 119 | public void setProbabilityIndex(double[][] probabilityIndex) { 120 | this.probabilityIndex = probabilityIndex; 121 | } 122 | 123 | 124 | /** 125 | * As a heuristic, some candidate edges may be trimmed and replaced by a logical axiom 126 | * 127 | * @return the probabilisticEdgeReplacementMap 128 | */ 129 | public Map getProbabilisticEdgeReplacementMap() { 130 | return probabilisticEdgeReplacementMap; 131 | } 132 | 133 | 134 | /** 135 | * @param probabilisticEdgeReplacementMap the probabilisticEdgeReplacementMap to set 136 | */ 137 | public void setProbabilisticEdgeReplacementMap( 138 | Map probabilisticEdgeReplacementMap) { 139 | this.probabilisticEdgeReplacementMap = probabilisticEdgeReplacementMap; 140 | } 141 | 142 | 143 | 144 | /** 145 | * @return the eliminatedEdges 146 | */ 147 | public Set getEliminatedEdges() { 148 | return eliminatedEdges; 149 | } 150 | 151 | 152 | /** 153 | * @param eliminatedEdges the eliminatedEdges to set 154 | */ 155 | public void setEliminatedEdges(Set eliminatedEdges) { 156 | this.eliminatedEdges = eliminatedEdges; 157 | } 158 | 159 | 160 | /** 161 | * @param axiomPriorProbabilityMap the axiomPriorProbabilityMap to set 162 | */ 163 | public void setAxiomPriorProbabilityMap( 164 | Map axiomPriorProbabilityMap) { 165 | this.axiomPriorProbabilityMap = axiomPriorProbabilityMap; 166 | } 167 | 168 | 169 | public Double getAxiomPriorProbability(OWLAxiom axiom) { 170 | if (axiomPriorProbabilityMap.containsKey(axiom)) 171 | return axiomPriorProbabilityMap.get(axiom); 172 | else 173 | return null; 174 | } 175 | 176 | /** 177 | * Computes the {@link ProbabilisticGraph.setProbabilityIndex()} 178 | * 179 | * NOTE: if the probabilistic edge list changes, this must be recalculated 180 | * 181 | * @param probabilisticGraph 182 | */ 183 | public void calculateEdgeProbabilityMatrix(OWLDataFactory df) { 184 | 185 | List prEdges = getProbabilisticEdges(); 186 | int N = prEdges.size(); 187 | 188 | // both indices are keyed by the index of the prEdge list; 189 | // TODO - less dumb way of doing this 190 | OWLAxiom[][] axiomIndex = new OWLAxiom[N][4]; 191 | double[][] probabilityIndex = new double[N][4]; 192 | 193 | Map axiomPriorProbabilityMap = new HashMap<>(); 194 | 195 | // initialize 196 | for (int ei = 0; ei < N; ei++) { 197 | ProbabilisticEdge e = prEdges.get(ei); 198 | OWLClass sc = e.getSourceClass(); 199 | OWLClass tc = e.getTargetClass(); 200 | Map tpm = e.getProbabilityTable().getTypeProbabilityMap(); 201 | for (int j=0; j<4; j++) { 202 | OWLAxiom ax; 203 | Double pr; 204 | if (j==1) { 205 | ax = df.getOWLSubClassOfAxiom(sc, tc); 206 | pr =tpm.get(EdgeType.SUBCLASS_OF); 207 | } 208 | else if (j==2) { 209 | ax = df.getOWLSubClassOfAxiom(tc, sc); 210 | pr = tpm.get(EdgeType.SUPERCLASS_OF); 211 | } 212 | else if (j == 3) { 213 | ax = df.getOWLEquivalentClassesAxiom(sc, tc); 214 | pr = tpm.get(EdgeType.EQUIVALENT_TO); 215 | } 216 | else { 217 | OWLAnnotationProperty prop = df.getOWLAnnotationProperty(DIFFERENT_FROM); 218 | ax = df.getOWLAnnotationAssertionAxiom(prop, sc.getIRI(), tc.getIRI()); 219 | pr = 1 - (tpm.get(EdgeType.EQUIVALENT_TO) + tpm.get(EdgeType.SUBCLASS_OF) 220 | + tpm.get(EdgeType.SUPERCLASS_OF)); 221 | } 222 | //LOG.info("Pr["+ei+"]["+j+"]="+pr+" // "+ax); 223 | probabilityIndex[ei][j] = pr; 224 | axiomIndex[ei][j] = ax; 225 | axiomPriorProbabilityMap.put(ax, pr); 226 | if (axiomPriorProbabilityMap.get(ax) != pr) { 227 | LOG.error("ERROR: "+ax+" ***** "+pr); 228 | } 229 | } 230 | } 231 | setAxiomIndex(axiomIndex); 232 | setProbabilityIndex(probabilityIndex); 233 | setAxiomPriorProbabilityMap(axiomPriorProbabilityMap); 234 | } 235 | 236 | public int collapseReciprocals() { 237 | LOG.info("PRE-COLLAPSING RECIPROCALS:"+probabilisticEdges.size()); 238 | List newEdges = new ArrayList(); 239 | int n=0; 240 | for (ProbabilisticEdge e :probabilisticEdges) { 241 | OWLClass s = e.sourceClass; 242 | OWLClass t = e.targetClass; 243 | ProbabilisticEdge reciprocal = null; 244 | if (s.compareTo(t) == 1) { 245 | for (ProbabilisticEdge f :probabilisticEdges) { 246 | if (f.targetClass.equals(s) && 247 | f.sourceClass.equals(t)) { 248 | reciprocal = f; 249 | break; 250 | } 251 | } 252 | } 253 | if (reciprocal == null) { 254 | newEdges.add(e); 255 | } 256 | else { 257 | n++; 258 | // skip e, and make reciprocal = avg(e, reciprocal) 259 | LOG.warn("Merging reciprocal edges "+e+" <-> "+reciprocal); 260 | Map etm = e.getProbabilityTable().getTypeProbabilityMap(); 261 | Map ftm = reciprocal.getProbabilityTable().getTypeProbabilityMap(); 262 | 263 | // recall that ftm is the reciprocal, so for asymmetric relationships, 264 | // we use the reciprocal relationship type 265 | double p1 = 266 | avg(ftm.get(EdgeType.SUBCLASS_OF), 267 | etm.get(EdgeType.SUPERCLASS_OF)); 268 | double p2 = 269 | avg(ftm.get(EdgeType.SUPERCLASS_OF), 270 | etm.get(EdgeType.SUBCLASS_OF)); 271 | 272 | ftm.put(EdgeType.SUBCLASS_OF, p1); 273 | ftm.put(EdgeType.SUPERCLASS_OF, p2); 274 | 275 | ftm.put(EdgeType.EQUIVALENT_TO, 276 | avg(ftm.get(EdgeType.EQUIVALENT_TO), 277 | etm.get(EdgeType.EQUIVALENT_TO))); 278 | ftm.put(EdgeType.NONE, 279 | avg(ftm.get(EdgeType.NONE), 280 | etm.get(EdgeType.NONE))); 281 | 282 | LOG.warn(" MERGED: "+reciprocal); 283 | 284 | } 285 | } 286 | probabilisticEdges = newEdges; 287 | LOG.info("POST-COLLAPSING RECIPROCALS:"+probabilisticEdges.size()); 288 | return n; 289 | } 290 | 291 | private double avg(double x, double y) { 292 | return (x+y)/2; 293 | } 294 | 295 | public OWLOntology createSubOntology(OWLOntologyManager mgr, IRI ontologyIRI, OWLOntology parentOnt) throws OWLOntologyCreationException { 296 | OWLOntology ont = mgr.createOntology(ontologyIRI); 297 | mgr.addAxioms(ont, getLogicalEdges()); 298 | mgr.addAxioms(ont, probabilisticEdgeReplacementMap.keySet()); 299 | for (OWLClass c: ont.getClassesInSignature()) { 300 | Set aaas = parentOnt.getAnnotationAssertionAxioms(c.getIRI()); 301 | mgr.addAxioms(ont, aaas); 302 | } 303 | OWLAnnotationProperty xprop = mgr.getOWLDataFactory().getOWLAnnotationProperty(IRI.create("http://www.geneontology.org/formats/oboInOwl#hasDbXref")); 304 | for (ProbabilisticEdge e : getProbabilisticEdges()) { 305 | OWLAxiom ax = mgr.getOWLDataFactory().getOWLAnnotationAssertionAxiom(xprop, e.getSourceClass().getIRI(), e.getTargetClass().getIRI()); 306 | mgr.addAxiom(ont, ax); 307 | } 308 | return ont; 309 | } 310 | 311 | } 312 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/model/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Datamodel for probabilistic graphs. 3 | * 4 | * The top-level class is {@link ProbabilsticGraph} 5 | * 6 | * @author cjm 7 | * 8 | */ 9 | package org.monarchinitiative.boom.model; -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author cjm 6 | * 7 | */ 8 | package org.monarchinitiative.boom; -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/runner/MarkdownRunner.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.runner; 2 | 3 | import java.io.IOException; 4 | import java.util.Set; 5 | import java.util.stream.Collectors; 6 | 7 | import org.monarchinitiative.boom.compute.ProbabilisticGraphCalculator; 8 | import org.monarchinitiative.boom.io.CliqueSolutionDotWriter; 9 | import org.monarchinitiative.boom.io.LabelProvider; 10 | import org.monarchinitiative.boom.model.CliqueSolution; 11 | import org.monarchinitiative.boom.model.LabelUtil; 12 | import org.monarchinitiative.boom.model.ProbabilisticGraph; 13 | import org.semanticweb.owlapi.io.OWLObjectRenderer; 14 | import org.semanticweb.owlapi.manchestersyntax.renderer.ManchesterOWLSyntaxOWLObjectRendererImpl; 15 | import org.semanticweb.owlapi.model.OWLOntology; 16 | import org.semanticweb.owlapi.model.OWLOntologyCreationException; 17 | 18 | /** 19 | * Runs a PGP and writes markdown report per-clique; 20 | * also generates dot and png 21 | * 22 | * @author cjm 23 | * 24 | */ 25 | public class MarkdownRunner { 26 | 27 | OWLOntology ontology; 28 | ProbabilisticGraph pg; 29 | String imageFilesPath = "target/img-"; 30 | OWLObjectRenderer renderer; 31 | 32 | public MarkdownRunner(OWLOntology ontology, ProbabilisticGraph pg) { 33 | super(); 34 | this.ontology = ontology; 35 | this.pg = pg; 36 | pg.calculateEdgeProbabilityMatrix(ontology.getOWLOntologyManager().getOWLDataFactory()); 37 | 38 | LabelProvider provider = new LabelProvider(ontology); 39 | renderer = new ManchesterOWLSyntaxOWLObjectRendererImpl(); 40 | renderer.setShortFormProvider(provider); 41 | 42 | } 43 | 44 | 45 | 46 | public Set runAll() throws OWLOntologyCreationException, IOException { 47 | ProbabilisticGraphCalculator pgp = new ProbabilisticGraphCalculator(ontology); 48 | return runAll(pgp); 49 | } 50 | 51 | public Set runAll(ProbabilisticGraphCalculator pgp) throws OWLOntologyCreationException, IOException { 52 | 53 | pgp.setProbabilisticGraph(pg); 54 | Set rpts = pgp.solveAllCliques(); 55 | 56 | for (CliqueSolution cs : rpts) { 57 | System.out.println(render(cs)); 58 | //CliqueSolutionDotWriter dw = new CliqueSolutionDotWriter(cs, ontology); 59 | //dw.renderToFile(path); 60 | } 61 | return rpts; 62 | 63 | } 64 | 65 | 66 | 67 | public String render(Set rpts) { 68 | return rpts.stream().map( (cs) -> render(cs) ).collect(Collectors.joining()); 69 | } 70 | 71 | public String render(CliqueSolution cs) { 72 | CliqueSolutionDotWriter dw = new CliqueSolutionDotWriter(cs, ontology, pg); 73 | String png; 74 | try { 75 | png = dw.renderToFile(imageFilesPath); 76 | String header = "\n\n## " + cs.cliqueId + "\n\n"; 77 | String prStats = " * __Pr(G)__=" + cs.probability+" CONFIDENCE=" + cs.confidence+" Success:" + cs.solved; 78 | String stats = " * __SIZE__=" + cs.size+" ("+cs.axioms.size()+" new axioms) "; 79 | String link = "[img]("+png+")"; 80 | //String axioms = cs.axioms.stream().map( (ax) -> " * " + LabelUtil.render(ax, ontology) + "\n" ).collect(Collectors.joining("")); 81 | String messages = cs.messages.stream().map( (m) -> " * MESSAGE: " + m + "\n" ).collect(Collectors.joining("")); 82 | String members = cs.classes.stream().map( (c) -> " * MEMBER: " + renderer.render(c) + "\n" ).collect(Collectors.joining("")); 83 | String axioms = cs.axioms.stream().map( (ax) -> " * " + 84 | renderer.render(ax) + 85 | " Pr= " + pg.getAxiomPriorProbability(ax) + 86 | "\n" ).collect(Collectors.joining("")); 87 | 88 | return header + prStats + "\n" + stats + "\n" + link + "\n" + members + messages + axioms; 89 | } catch (IOException e) { 90 | // TODO Auto-generated catch block 91 | e.printStackTrace(); 92 | return ""; 93 | } 94 | 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /boom-core/src/main/java/org/monarchinitiative/boom/runner/RunEngine.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.boom.runner; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Set; 8 | import java.util.stream.Collectors; 9 | 10 | import org.apache.commons.io.FileUtils; 11 | import org.apache.log4j.Level; 12 | import org.apache.log4j.Logger; 13 | import org.monarchinitiative.boom.compute.ProbabilisticGraphCalculator; 14 | import org.monarchinitiative.boom.io.IDTools; 15 | import org.monarchinitiative.boom.io.OWLLoader; 16 | import org.monarchinitiative.boom.io.ProbabilisticGraphParser; 17 | import org.monarchinitiative.boom.model.CliqueSolution; 18 | import org.monarchinitiative.boom.model.ProbabilisticGraph; 19 | import org.semanticweb.owlapi.model.IRI; 20 | import org.semanticweb.owlapi.model.OWLClass; 21 | import org.semanticweb.owlapi.model.OWLOntology; 22 | import org.semanticweb.owlapi.model.OWLOntologyCreationException; 23 | import org.semanticweb.owlapi.model.OWLOntologyStorageException; 24 | 25 | import com.beust.jcommander.JCommander; 26 | import com.beust.jcommander.Parameter; 27 | import com.google.gson.Gson; 28 | import com.google.gson.GsonBuilder; 29 | 30 | public class RunEngine { 31 | 32 | @Parameter(names = { "-v", "--verbose" }, description = "Level of verbosity") 33 | private Integer verbose = 1; 34 | 35 | @Parameter(names = { "-o", "--out"}, description = "output ontology file") 36 | private String outpath; 37 | 38 | @Parameter(names = { "-c", "--classes"}, description = "Run only on cliques containing these classes") 39 | private List classIds; 40 | 41 | @Parameter(names = { "-r", "--roots"}, description = "Run only on cliques traceable to these root superclasses") 42 | private List rootClassIds; 43 | 44 | @Parameter(names = { "-j", "--json"}, description = "output json report file") 45 | private String jsonOutPath; 46 | 47 | @Parameter(names = { "-t", "--table"}, description = "Path to TSV of probability table") 48 | private String ptableFile; 49 | 50 | @Parameter(names = { "-m", "--markdown"}, description = "Path to output markdown file") 51 | private String mdOutputFile; 52 | 53 | @Parameter(names = { "-d", "--dir"}, description = "directory") 54 | private String dir = "."; 55 | 56 | @Parameter(names = { "-n", "--new"}, description = "Make new ontology") 57 | private Boolean isMakeNewOntology = false; 58 | 59 | @Parameter(names = { "--max" }, description = "Maximumum number of probabilistic edges in clique") 60 | private Integer maxProbabilisticEdges = 9; 61 | 62 | @Parameter(names = { "--splitSize" }, description = "Threshold at which heuristic procedure is used to split clique") 63 | private Integer cliqueSplitSize = 6; 64 | 65 | @Parameter(names = { "--experimental" }, description = "Experimental") 66 | private Boolean isExperimental = false; 67 | 68 | @Parameter(names = {"-h", "--help"}, help = true) 69 | private boolean help = false; 70 | 71 | @Parameter(description = "Files") 72 | private List files = new ArrayList<>(); 73 | 74 | 75 | 76 | public static void main(String ... args) throws OWLOntologyCreationException, IOException, OWLOntologyStorageException { 77 | RunEngine main = new RunEngine(); 78 | JCommander jCommander = new JCommander(main, args); 79 | if (main.help) { 80 | jCommander.usage(); 81 | return; 82 | } 83 | main.run(); 84 | } 85 | 86 | public void run() throws OWLOntologyCreationException, IOException, OWLOntologyStorageException { 87 | Logger.getLogger("org.semanticweb.elk").setLevel(Level.OFF); 88 | 89 | //System.out.printf("%s %d %s", groups, verbose, debug); 90 | OWLLoader loader = new OWLLoader(); 91 | OWLOntology sourceOntology; 92 | sourceOntology = loader.load(files.get(0)); 93 | ProbabilisticGraphParser parser = 94 | new ProbabilisticGraphParser(sourceOntology); 95 | 96 | ProbabilisticGraph pg = 97 | parser.parse(ptableFile); 98 | MarkdownRunner mdr = new MarkdownRunner(sourceOntology, pg); 99 | 100 | ProbabilisticGraphCalculator pgc = new ProbabilisticGraphCalculator(sourceOntology); 101 | 102 | pgc.setProbabilisticGraph(pg); 103 | if (maxProbabilisticEdges != null) 104 | pgc.setMaxProbabilisticEdges(maxProbabilisticEdges); 105 | if (cliqueSplitSize != null) 106 | pgc.setCliqueSplitSize(cliqueSplitSize); 107 | pgc.isExperimental = isExperimental; 108 | if (isExperimental) 109 | System.out.println("EXPERIMENTAL MODE"); 110 | 111 | if (classIds != null && classIds.size() > 0) { 112 | Set filterOnClasses = 113 | classIds.stream().map( s -> 114 | pgc.getOWLDataFactory().getOWLClass(IDTools.getIRIByIdentifier(s))).collect(Collectors.toSet()); 115 | pgc.setFilterOnClasses(filterOnClasses); 116 | } 117 | if (rootClassIds != null && rootClassIds.size() > 0) { 118 | Set roots = 119 | rootClassIds.stream().map( s -> 120 | pgc.getOWLDataFactory().getOWLClass(IDTools.getIRIByIdentifier(s))).collect(Collectors.toSet()); 121 | pgc.setFilterOnRootClasses(roots); 122 | } 123 | 124 | if (dir != null) { 125 | if (mdOutputFile == null) { 126 | mdOutputFile = dir + "/kboom-report.md"; 127 | } 128 | if (jsonOutPath == null) { 129 | jsonOutPath = dir + "/kboom-report.json"; 130 | } 131 | mdr.imageFilesPath = dir + "/images/"; 132 | } 133 | 134 | Set rpts = pgc.solveAllCliques(); 135 | 136 | if (mdOutputFile != null) { 137 | FileUtils.writeStringToFile(new File(mdOutputFile), mdr.render(rpts)); 138 | } 139 | 140 | OWLOntology outputOntology; 141 | if (isMakeNewOntology) { 142 | outputOntology = sourceOntology.getOWLOntologyManager().createOntology(); 143 | for (CliqueSolution cs : rpts) { 144 | sourceOntology.getOWLOntologyManager().addAxioms(outputOntology, cs.axioms); 145 | } 146 | } 147 | else { 148 | outputOntology = pgc.getSourceOntology(); 149 | } 150 | 151 | 152 | Gson w = new GsonBuilder(). 153 | setPrettyPrinting(). 154 | serializeSpecialFloatingPointValues(). 155 | excludeFieldsWithoutExposeAnnotation(). 156 | create(); 157 | String s = w.toJson(rpts); 158 | if (jsonOutPath == null) 159 | System.out.println(s); 160 | else 161 | FileUtils.writeStringToFile(new File(jsonOutPath), s); 162 | 163 | if (outpath == null) 164 | outpath = "foo.owl"; 165 | 166 | File file = new File(outpath); 167 | sourceOntology.getOWLOntologyManager().saveOntology(outputOntology, IRI.create(file)); 168 | 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /boom-core/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.console=org.apache.log4j.ConsoleAppender 2 | log4j.appender.console.layout=org.apache.log4j.PatternLayout 3 | log4j.appender.console.layout.ConversionPattern=%-5p %m%n 4 | #log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p %c - %m%n 5 | log4j.logger.user=DEBUG 6 | #log4j.rootLogger=WARN, console 7 | log4j.rootLogger=INFO, console 8 | -------------------------------------------------------------------------------- /boom-core/src/test/java/org/monarchinitiative/owlbag/compute/ProbabilisticGraphCalculatorTest.java: -------------------------------------------------------------------------------- 1 | package org.monarchinitiative.owlbag.compute; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import java.io.File; 6 | import java.io.FileOutputStream; 7 | import java.io.IOException; 8 | import java.util.Set; 9 | 10 | import org.apache.log4j.Level; 11 | import org.apache.log4j.Logger; 12 | import org.junit.Test; 13 | import org.monarchinitiative.boom.compute.ProbabilisticGraphCalculator; 14 | import org.monarchinitiative.boom.io.OWLLoader; 15 | import org.monarchinitiative.boom.io.ProbabilisticGraphParser; 16 | import org.monarchinitiative.boom.model.CliqueSolution; 17 | import org.monarchinitiative.boom.model.ProbabilisticEdge; 18 | import org.monarchinitiative.boom.model.ProbabilisticGraph; 19 | import org.monarchinitiative.boom.runner.MarkdownRunner; 20 | import org.obolibrary.oboformat.parser.OBOFormatParserException; 21 | import org.semanticweb.owlapi.formats.RDFXMLDocumentFormat; 22 | import org.semanticweb.owlapi.model.IRI; 23 | import org.semanticweb.owlapi.model.OWLAnnotationProperty; 24 | import org.semanticweb.owlapi.model.OWLAxiom; 25 | import org.semanticweb.owlapi.model.OWLDataFactory; 26 | import org.semanticweb.owlapi.model.OWLOntology; 27 | import org.semanticweb.owlapi.model.OWLOntologyCreationException; 28 | import org.semanticweb.owlapi.model.OWLOntologyStorageException; 29 | import org.semanticweb.owlapi.reasoner.OWLReasoner; 30 | 31 | import com.google.gson.Gson; 32 | import com.google.gson.GsonBuilder; 33 | import com.google.monitoring.runtime.instrumentation.common.com.google.common.io.Resources; 34 | 35 | public class ProbabilisticGraphCalculatorTest { 36 | 37 | private static Logger LOG = Logger.getLogger(ProbabilisticGraphCalculatorTest.class); 38 | 39 | OWLLoader loader = new OWLLoader(); 40 | OWLOntology ontology; 41 | 42 | class ExpectedAxiom { 43 | OWLAxiom axiom; 44 | boolean isExpected = true; 45 | public ExpectedAxiom(OWLAxiom axiom) { 46 | super(); 47 | this.axiom = axiom; 48 | } 49 | 50 | 51 | } 52 | 53 | 54 | 55 | @Test 56 | public void testBasic() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 57 | // fake ontology. fake OMIM IDs in flat hierarchy. 58 | // Two additional hierarchies, X and Y 59 | 60 | runUsingResources("basic.obo", "ptable-basic.tsv", "basic-resolved.owl", 61 | // all OMIMs are mapped to Z:3, we expect these to be resolved as SubClassOfs. 62 | // note this also tests heuristic clique-breaking 63 | subclass("OMIM_001", "Z_3"), 64 | subclass("OMIM_002", "Z_3"), 65 | subclass("OMIM_003", "Z_3"), 66 | subclass("OMIM_004", "Z_3"), 67 | subclass("OMIM_005", "Z_3"), 68 | subclass("OMIM_006", "Z_3"), 69 | subclass("OMIM_007", "Z_3"), 70 | subclass("OMIM_008", "Z_3"), 71 | subclass("OMIM_009", "Z_3"), 72 | subclass("OMIM_010", "Z_3"), 73 | // note that even through the prior for equivalence here is high, 74 | // it should be resolved as SubClassOf, when the full network is considered 75 | subclass("OMIM_010", "X_3"), 76 | 77 | // the priors for equivalence for all 3 Zs to this one Y is high; 78 | // however, maximally one can be equivalent to be consistent. 79 | subclass("Z_2b1a", "Y_2b1"), 80 | subclass("Z_2b1b", "Y_2b1"), 81 | equiv("Z_2b1c", "Y_2b1"), // prior for equivalence is slightly higher 82 | 83 | subclass("Z_2a", "X_2"), 84 | equiv("Y_1", "X_1"), 85 | equiv("Y_2", "X_2"), 86 | equiv("Y_2", "Z_2"), 87 | equiv("X_3", "Z_3") 88 | 89 | ); 90 | } 91 | 92 | @Test 93 | public void testDisjoint() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 94 | // cliques should not have subclasses of two disjointclasses 95 | 96 | Set solns = 97 | runUsingResources("disjoint_test.obo", 98 | "ptable-disjoint.tsv", 99 | "disjoint-resolved.owl", 100 | 101 | notEquiv("Y_1c", "X_2c"), // P=0.8; but this would violate Disjoint(X_1 X_2) 102 | equiv("Y_1c", "X_1c"), 103 | equiv("Y_1cA", "X_1cA"), 104 | equiv("Y_2c", "X_2c"), 105 | 106 | notSubclass("Y_1", "X_1"), 107 | equiv("Y_1", "X_1"), 108 | equiv("Y_root", "X_root") 109 | 110 | ); 111 | } 112 | 113 | @Test 114 | public void testUnsatFromGreedy() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 115 | // The greedy clique reduction strategy has the possibility of introducing 116 | // unsatisfiable states. 117 | // Here we assign OMIM:010 high probabilities of being equivalent to both X:3 and X:2 118 | 119 | runUsingResources("basic.obo", "ptable-unsat-clique-test.tsv", "greedy-resolved.owl", 120 | subclass("OMIM_001", "Z_3"), 121 | subclass("OMIM_002", "Z_3"), 122 | subclass("OMIM_003", "Z_3"), 123 | subclass("OMIM_004", "Z_3"), 124 | subclass("OMIM_005", "Z_3"), 125 | subclass("OMIM_006", "Z_3"), 126 | subclass("OMIM_007", "Z_3"), 127 | subclass("OMIM_008", "Z_3"), 128 | subclass("OMIM_009", "Z_3"), 129 | subclass("OMIM_010", "Z_3"), 130 | 131 | // OMIM_010 has high prior for both X_2 and X_3; 132 | // X_3 has higher prob than X_2 133 | // assigning both would result in an invalid ontology 134 | equiv("OMIM_010", "X_3"), 135 | subclass("X_3", "Z_3"), 136 | // -- 137 | 138 | subclass("Z_2b1a", "Y_2b1"), 139 | subclass("Z_2b1b", "Y_2b1"), 140 | equiv("Z_2b1c", "Y_2b1"), 141 | 142 | subclass("Z_2a", "X_2"), 143 | equiv("Y_1", "X_1"), 144 | equiv("Y_2", "X_2"), 145 | equiv("Y_2", "Z_2") 146 | 147 | ); 148 | } 149 | 150 | @Test 151 | public void testUnsatFromGreedy2() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 152 | // The greedy clique reduction strategy has the possibility of introducing 153 | // unsatisfiable states. 154 | // Here we assign OMIM:010 high probabilities of being equivalent to both X:3 and X:2 155 | 156 | runUsingResources("basic.obo", "ptable-unsat-clique-test2.tsv", "greedy2-resolved.owl", 157 | subclass("OMIM_001", "Z_3"), 158 | subclass("OMIM_002", "Z_3"), 159 | subclass("OMIM_003", "Z_3"), 160 | subclass("OMIM_004", "Z_3"), 161 | subclass("OMIM_005", "Z_3"), 162 | subclass("OMIM_006", "Z_3"), 163 | subclass("OMIM_007", "Z_3"), 164 | subclass("OMIM_008", "Z_3"), 165 | subclass("OMIM_009", "Z_3"), 166 | subclass("OMIM_010", "Z_3"), 167 | 168 | // OMIM_010 has high prior for both X_2 and X_3; 169 | // X_3 has higher prob than X_2 170 | // assigning both would result in an invalid ontology 171 | equiv("OMIM_010", "X_3"), 172 | subclass("X_3", "Z_3"), 173 | // -- 174 | 175 | subclass("Z_2b1a", "Y_2b1"), 176 | subclass("Z_2b1b", "Y_2b1"), 177 | equiv("Z_2b1c", "Y_2b1"), 178 | 179 | subclass("Z_2a", "X_2"), 180 | equiv("Y_1", "X_1"), 181 | equiv("Y_2", "X_2"), 182 | equiv("Y_2", "Z_2") 183 | 184 | ); 185 | } 186 | 187 | @Test 188 | public void testTrivialCombos() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 189 | 190 | Set solns = 191 | runUsingResources("trivial-4-combos.obo", "ptable-trivial-4-combos.tsv", "trivial-4-combos-resolved.owl", 192 | subclass("A_1", "B_1"), 193 | subclass("B_2", "A_2"), 194 | equiv("A_3", "B_3") 195 | ); 196 | assertEquals(4, solns.size()); 197 | CliqueSolution s = solns.iterator().next(); 198 | //assertTrue("low confidence expected", s.confidence < 0.1); 199 | } 200 | 201 | @Test 202 | public void testReciprocalConflict() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 203 | // Pr(X1 solns = 207 | runUsingResources("basic.obo", "ptable-reciprocal-conflict.tsv", "reciprocal-conflict-resolved.owl", 208 | subclass("X_1", "Y_1") 209 | ); 210 | assertEquals(1, solns.size()); 211 | CliqueSolution s = solns.iterator().next(); 212 | assertTrue("low confidence expected", s.confidence < 0.1); 213 | } 214 | 215 | @Test 216 | public void testUnsatisfiable() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 217 | // Pr(X1 solns = 221 | runUsingResources("basic.obo", "ptable-unsatisfiable.tsv", "unsatisfiable-resolved.owl" 222 | ); 223 | assertEquals(1, solns.size()); 224 | CliqueSolution s = solns.iterator().next(); 225 | assertTrue("this clique has no solution", !s.solved); 226 | } 227 | 228 | @Test 229 | public void testNoSolutionsDueToGreedy() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 230 | // Pr(X1 solns = 234 | runUsingResources("nosol.obo", "ptable-nosol.tsv", "nosol-resolved.owl" 235 | ); 236 | assertEquals(1, solns.size()); 237 | CliqueSolution s = solns.iterator().next(); 238 | assertTrue("this clique has no solution", !s.solved); 239 | } 240 | 241 | 242 | 243 | @Test 244 | public void testOneSolution() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 245 | // Pr(X1 solns = 249 | runUsingResources("basic.obo", "ptable-one-solution.tsv", "one-solution-resolved.owl" 250 | ); 251 | assertEquals(1, solns.size()); 252 | CliqueSolution s = solns.iterator().next(); 253 | assertEquals("this clique has a single solution, which is to reject the proposed axiom", 254 | 1, s.axioms.size()); 255 | } 256 | 257 | 258 | /** 259 | * In some cases a weighted axiom may be provided where a hard logical axiom already exists. 260 | * In these cases, the weighted axioms corresponding to an edge should be pruned in advance. 261 | * 262 | * E.g. if O = SubClassOf(A,B), and H = {Pr(SubClassOf(A,B)=0.2)}, then H will be reduced to {}. 263 | * 264 | * Note that the hard subclass axiom between A and B is still retained in the combined ontology 265 | * 266 | * @throws OWLOntologyCreationException 267 | * @throws OBOFormatParserException 268 | * @throws IOException 269 | * @throws OWLOntologyStorageException 270 | */ 271 | @Test 272 | public void testOverride() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 273 | // Pr(X1b solns = 277 | runUsingResources("basic.obo", "ptable-override.tsv", "override-resolved.owl" 278 | ); 279 | assertEquals(1, solns.size()); 280 | CliqueSolution s = solns.iterator().next(); 281 | assertEquals("this clique has a single solution, which is to accept the proposed axiom", 282 | 1, s.axioms.size()); 283 | } 284 | 285 | @Test 286 | public void testAssertedSubClass() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 287 | 288 | Set solns = 289 | runUsingResources("x-ontology-subclass.obo", "ptable-asserted-subclass.tsv", "asserted-subclass-resolved.owl" 290 | ); 291 | assertEquals(1, solns.size()); 292 | long nSolved = solns.stream().filter(s -> s.solved).count(); 293 | assertEquals(0, nSolved); 294 | } 295 | 296 | @Test 297 | public void testCaseXlid() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 298 | // Pr(X1b solns = 302 | runUsingResources("cases/xlid.obo", "cases/xlid-ptable.tsv", "foo.owl" 303 | ); 304 | long nFailed = solns.stream().filter(s -> !s.solved).count(); 305 | assertEquals(0, nFailed); 306 | } 307 | 308 | 309 | @Test 310 | public void testEntailed() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 311 | // Pr(X1b nonPrEdges = pgc.findEntailedProbabilisticEdges(pgc.getProbabilisticGraph(), reasoner); 318 | reasoner.dispose(); 319 | System.out.println(nonPrEdges); 320 | assertEquals(1, nonPrEdges.size()); 321 | } 322 | 323 | @Test 324 | public void testFalsePositive() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 325 | // in this test, OMIM:1xx is aligned with Y 326 | // and OMIM:2xx is aligned with Z 327 | // fake join point 328 | // **OMIM:101 Z:2b1c 0.8 0.08 0.1 0.02 329 | 330 | Set solns = 331 | runUsingResources("basic-fp.obo", "ptable-false-positive.tsv", "fp-resolved.owl", 332 | subclass("OMIM_101", "Y_1a1"), 333 | subclass("OMIM_101", "X_2b") 334 | ); 335 | assertEquals(3, solns.size()); 336 | } 337 | 338 | @Test 339 | public void testFalsePositiveNoTieBreaker() throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 340 | // same as previous test, we have a false link 341 | // OMIM:101 Z:2b1c 0.8 0.08 0.1 0.02 342 | // but we lack X:2b to break the tie, resulting in 101 going into its own clique 343 | 344 | Set solns = 345 | runUsingResources("basic-fp.obo", "ptable-false-positive2.tsv", "fp-resolved.owl" 346 | ); 347 | assertEquals(4, solns.size()); 348 | } 349 | 350 | 351 | public IRI getIRI(String c) { 352 | return IRI.create("http://purl.obolibrary.org/obo/"+c); 353 | } 354 | 355 | public OWLDataFactory df() { 356 | return loader.getOWLOntologyManager().getOWLDataFactory(); 357 | } 358 | 359 | 360 | 361 | 362 | public ExpectedAxiom different(String c1, String c2) { 363 | OWLAnnotationProperty prop = df().getOWLAnnotationProperty(ProbabilisticGraph.DIFFERENT_FROM); 364 | return new ExpectedAxiom(df().getOWLAnnotationAssertionAxiom(prop, getIRI(c1), getIRI(c2))); 365 | } 366 | 367 | public ExpectedAxiom equiv(String c1, String c2) { 368 | return new ExpectedAxiom(df().getOWLEquivalentClassesAxiom( 369 | df().getOWLClass(getIRI(c1)), 370 | df().getOWLClass(getIRI(c2)))); 371 | 372 | } 373 | 374 | public ExpectedAxiom subclass(String c1, String c2) { 375 | return new ExpectedAxiom(df().getOWLSubClassOfAxiom( 376 | df().getOWLClass(getIRI(c1)), 377 | df().getOWLClass(getIRI(c2)))); 378 | 379 | } 380 | 381 | public ExpectedAxiom notSubclass(String c1, String c2) { 382 | ExpectedAxiom ea = subclass(c1, c2); 383 | ea.isExpected = false; 384 | return ea; 385 | 386 | } 387 | 388 | public ExpectedAxiom notEquiv(String c1, String c2) { 389 | ExpectedAxiom ea = equiv(c1, c2); 390 | ea.isExpected = false; 391 | return ea; 392 | 393 | } 394 | 395 | 396 | public boolean solutionsContainAxiom(Set cliques, OWLAxiom ea) { 397 | 398 | for (CliqueSolution c : cliques) { 399 | for (OWLAxiom a : c.axioms) { 400 | if (a.equals(ea)) 401 | return true; 402 | } 403 | } 404 | return false; 405 | } 406 | 407 | 408 | public Set runUsingResources(String ontFile, String ptableFile, String outpath, 409 | ExpectedAxiom... expectedAxioms) throws OWLOntologyCreationException, OBOFormatParserException, IOException, OWLOntologyStorageException { 410 | Set cliques = 411 | runUsingPaths(Resources.getResource(ontFile).getFile(), 412 | getResource(ptableFile).getAbsolutePath(), 413 | "target/" + outpath 414 | ); 415 | for (ExpectedAxiom ea : expectedAxioms) { 416 | OWLAxiom a = ea.axiom; 417 | if (ea.isExpected) { 418 | assertTrue("does not contain: "+a, 419 | solutionsContainAxiom(cliques,a)); 420 | } 421 | else { 422 | assertTrue("unexpectedly contains: "+a, 423 | !solutionsContainAxiom(cliques,a)); 424 | 425 | } 426 | } 427 | 428 | return cliques; 429 | } 430 | 431 | public Set runUsingPaths(String ontFile, String ptablePath, String outpath) throws IOException, OWLOntologyCreationException, OWLOntologyStorageException { 432 | LOG.info("ONT: "+ontFile); 433 | LOG.info("PROBS: "+ptablePath); 434 | Logger.getLogger("org.semanticweb.elk").setLevel(Level.OFF); 435 | ontology = loader.loadOWL(ontFile); 436 | ProbabilisticGraphParser parser = 437 | new ProbabilisticGraphParser(ontology); 438 | ProbabilisticGraph pg = 439 | parser.parse(ptablePath); 440 | MarkdownRunner mdr = new MarkdownRunner(ontology, pg); 441 | ProbabilisticGraphCalculator pgp = new ProbabilisticGraphCalculator(ontology); 442 | pgp.setMaxProbabilisticEdges(5); 443 | Set rpts = mdr.runAll(pgp); 444 | 445 | Gson w = new GsonBuilder(). 446 | setPrettyPrinting(). 447 | excludeFieldsWithoutExposeAnnotation(). 448 | serializeSpecialFloatingPointValues(). 449 | create(); 450 | String s = w.toJson(rpts); 451 | System.out.println(s); 452 | 453 | for (CliqueSolution cs : rpts) { 454 | ontology.getOWLOntologyManager().addAxioms(ontology, cs.axioms); 455 | for (OWLAxiom a : cs.axioms) { 456 | System.err.println(pgp.render(a)); 457 | } 458 | } 459 | 460 | 461 | 462 | File outfile = new File(outpath); 463 | FileOutputStream os = new FileOutputStream(outfile); 464 | //IOUtils.write("FOO", os); 465 | System.err.println("Saving to "+outfile+" "+os+" "+ontology.getAxiomCount()); 466 | ontology.getOWLOntologyManager().saveOntology(ontology, new RDFXMLDocumentFormat(), os); 467 | os.close(); 468 | return rpts; 469 | 470 | } 471 | 472 | protected static String getResourceAsAbsolutePath(String name) { 473 | return getResource(name).getAbsolutePath(); 474 | } 475 | 476 | protected static String getResourceAsUrlPath(String name) { 477 | return Resources.getResource(name).getFile(); 478 | } 479 | 480 | 481 | protected static File getResource(String name) { 482 | assertNotNull(name); 483 | assertFalse(name.length() == 0); 484 | // TODO replace this with a mechanism not relying on the relative path 485 | File file = new File("src/test/resources/"+name); 486 | assertTrue("Requested resource does not exists: "+file, file.exists()); 487 | return file; 488 | } 489 | 490 | 491 | 492 | } 493 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/basic-fp.obo: -------------------------------------------------------------------------------- 1 | ontology: x 2 | remark: fake ontology. fake OMIM IDs in flat hierarchy. Two additional hierarchies, X and Y 3 | 4 | [Term] 5 | id: X:root 6 | 7 | [Term] 8 | id: X:1 9 | name: x1 10 | is_a: X:root 11 | 12 | [Term] 13 | id: X:2 14 | is_a: X:root 15 | name: "x2" 16 | 17 | [Term] 18 | id: X:3 19 | is_a: X:root 20 | 21 | [Term] 22 | id: X:1a 23 | is_a: X:1 24 | 25 | [Term] 26 | id: X:1b 27 | is_a: X:1 28 | 29 | [Term] 30 | id: X:2a 31 | is_a: X:2 32 | 33 | [Term] 34 | id: X:2b 35 | is_a: X:2 36 | 37 | [Term] 38 | id: Y:root 39 | 40 | [Term] 41 | id: Y:1 42 | is_a: Y:root 43 | 44 | [Term] 45 | id: Y:2 46 | is_a: Y:root 47 | 48 | [Term] 49 | id: Y:1a 50 | is_a: Y:1 51 | 52 | [Term] 53 | id: Y:1a1 54 | is_a: Y:1a 55 | 56 | [Term] 57 | id: W:1a1 58 | 59 | [Term] 60 | id: Y:1b 61 | is_a: Y:1 62 | 63 | [Term] 64 | id: Y:2a 65 | is_a: Y:2 66 | 67 | [Term] 68 | id: Y:2b 69 | is_a: Y:2 70 | 71 | [Term] 72 | id: Y:2b1 73 | is_a: Y:2b 74 | 75 | [Term] 76 | id: Z:root 77 | 78 | [Term] 79 | id: Z:1 80 | is_a: Z:root 81 | 82 | [Term] 83 | id: Z:2 84 | is_a: Z:root 85 | 86 | [Term] 87 | id: Z:3 88 | is_a: Z:root 89 | 90 | [Term] 91 | id: Z:1a 92 | is_a: Z:1 93 | 94 | [Term] 95 | id: Z:1b 96 | is_a: Z:1 97 | 98 | [Term] 99 | id: Z:2a 100 | is_a: Z:2 101 | 102 | [Term] 103 | id: Z:2b 104 | is_a: Z:2 105 | 106 | [Term] 107 | id: Z:2b1 108 | is_a: Z:2b 109 | 110 | [Term] 111 | id: Z:2b1a 112 | is_a: Z:2b1 113 | 114 | [Term] 115 | id: Z:2b1b 116 | is_a: Z:2b1 117 | 118 | [Term] 119 | id: Z:2b1c 120 | is_a: Z:2b1 121 | 122 | [Term] 123 | id: OMIM:root 124 | 125 | [Term] 126 | id: OMIM:001 127 | is_a: OMIM:root 128 | 129 | [Term] 130 | id: OMIM:002 131 | is_a: OMIM:root 132 | 133 | [Term] 134 | id: OMIM:003 135 | is_a: OMIM:root 136 | 137 | [Term] 138 | id: OMIM:004 139 | is_a: OMIM:root 140 | 141 | [Term] 142 | id: OMIM:005 143 | is_a: OMIM:root 144 | 145 | [Term] 146 | id: OMIM:006 147 | is_a: OMIM:root 148 | 149 | [Term] 150 | id: OMIM:007 151 | is_a: OMIM:root 152 | 153 | [Term] 154 | id: OMIM:007 155 | is_a: OMIM:root 156 | 157 | [Term] 158 | id: OMIM:009 159 | is_a: OMIM:root 160 | 161 | [Term] 162 | id: OMIM:010 163 | is_a: OMIM:root 164 | 165 | [Term] 166 | id: OMIM:101 167 | is_a: OMIM:root 168 | 169 | [Term] 170 | id: OMIM:102 171 | is_a: OMIM:root 172 | 173 | [Term] 174 | id: OMIM:103 175 | is_a: OMIM:root 176 | 177 | [Term] 178 | id: OMIM:104 179 | is_a: OMIM:root 180 | 181 | [Term] 182 | id: OMIM:105 183 | is_a: OMIM:root 184 | 185 | [Term] 186 | id: OMIM:106 187 | is_a: OMIM:root 188 | 189 | [Term] 190 | id: OMIM:107 191 | is_a: OMIM:root 192 | 193 | [Term] 194 | id: OMIM:107 195 | is_a: OMIM:root 196 | 197 | [Term] 198 | id: OMIM:109 199 | is_a: OMIM:root 200 | 201 | [Term] 202 | id: OMIM:110 203 | is_a: OMIM:root 204 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/basic.obo: -------------------------------------------------------------------------------- 1 | ontology: x 2 | remark: fake ontology. fake OMIM IDs in flat hierarchy. Two additional hierarchies, X and Y 3 | 4 | [Term] 5 | id: X:root 6 | 7 | [Term] 8 | id: X:1 9 | name: x1 10 | is_a: X:root 11 | 12 | [Term] 13 | id: X:2 14 | is_a: X:root 15 | name: "x2" 16 | 17 | [Term] 18 | id: X:3 19 | is_a: X:root 20 | 21 | [Term] 22 | id: X:1a 23 | is_a: X:1 24 | 25 | [Term] 26 | id: X:1b 27 | is_a: X:1 28 | 29 | [Term] 30 | id: X:2a 31 | is_a: X:2 32 | 33 | [Term] 34 | id: X:2b 35 | is_a: X:2 36 | 37 | [Term] 38 | id: Y:root 39 | 40 | [Term] 41 | id: Y:1 42 | is_a: Y:root 43 | 44 | [Term] 45 | id: Y:2 46 | is_a: Y:root 47 | 48 | [Term] 49 | id: Y:1a 50 | is_a: Y:1 51 | 52 | [Term] 53 | id: Y:1a1 54 | is_a: Y:1a 55 | 56 | [Term] 57 | id: Y:1b 58 | is_a: Y:1 59 | 60 | [Term] 61 | id: Y:2a 62 | is_a: Y:2 63 | 64 | [Term] 65 | id: Y:2b 66 | is_a: Y:2 67 | 68 | [Term] 69 | id: Y:2b1 70 | is_a: Y:2b 71 | 72 | [Term] 73 | id: Z:root 74 | 75 | [Term] 76 | id: Z:1 77 | is_a: Z:root 78 | 79 | [Term] 80 | id: Z:2 81 | is_a: Z:root 82 | 83 | [Term] 84 | id: Z:3 85 | is_a: Z:root 86 | 87 | [Term] 88 | id: Z:1a 89 | is_a: Z:1 90 | 91 | [Term] 92 | id: Z:1b 93 | is_a: Z:1 94 | 95 | [Term] 96 | id: Z:2a 97 | is_a: Z:2 98 | 99 | [Term] 100 | id: Z:2b 101 | is_a: Z:2 102 | 103 | [Term] 104 | id: Z:2b1 105 | is_a: Z:2b 106 | 107 | [Term] 108 | id: Z:2b1a 109 | is_a: Z:2b1 110 | 111 | [Term] 112 | id: Z:2b1b 113 | is_a: Z:2b1 114 | 115 | [Term] 116 | id: Z:2b1c 117 | is_a: Z:2b1 118 | 119 | [Term] 120 | id: OMIM:root 121 | 122 | [Term] 123 | id: OMIM:001 124 | is_a: OMIM:root 125 | 126 | [Term] 127 | id: OMIM:002 128 | is_a: OMIM:root 129 | 130 | [Term] 131 | id: OMIM:003 132 | is_a: OMIM:root 133 | 134 | [Term] 135 | id: OMIM:004 136 | is_a: OMIM:root 137 | 138 | [Term] 139 | id: OMIM:005 140 | is_a: OMIM:root 141 | 142 | [Term] 143 | id: OMIM:006 144 | is_a: OMIM:root 145 | 146 | [Term] 147 | id: OMIM:007 148 | is_a: OMIM:root 149 | 150 | [Term] 151 | id: OMIM:007 152 | is_a: OMIM:root 153 | 154 | [Term] 155 | id: OMIM:009 156 | is_a: OMIM:root 157 | 158 | [Term] 159 | id: OMIM:010 160 | is_a: OMIM:root 161 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/cases/xlid-ptable.tsv: -------------------------------------------------------------------------------- 1 | DOID:1059 MESH:D008607 0.14 0.14 0.7 0.02 2 | DOID:1059 Orphanet:183757 0.02631578947368421 0.7631578947368421 0.15789473684210525 0.05263157894736842 3 | DOID:1059 Orphanet:87277 0.02631578947368421 0.7631578947368421 0.15789473684210525 0.05263157894736842 4 | DOID:150 MESH:D001523 0.2222222222222222 0.2222222222222222 0.4444444444444444 0.1111111111111111 5 | DOID:630 MESH:D030342 0.2222222222222222 0.2222222222222222 0.4444444444444444 0.1111111111111111 6 | DOID:863 MESH:D009422 0.2 0.2 0.5714285714285714 0.02857142857142857 7 | DOID:863 Orphanet:98006 0.02631578947368421 0.7631578947368421 0.15789473684210525 0.05263157894736842 8 | MESH:C537457 OMIM:309580 0.020833333333333332 0.020833333333333332 0.9583333333333334 0 9 | MESH:C537457 Orphanet:93972 0.3333333333333333 0.16666666666666666 0.3888888888888889 0.1111111111111111 10 | OMIM:309580 Orphanet:73220 0 0 1.0 0 11 | OMIM:309580 Orphanet:93970 0.23809523809523808 0.23809523809523808 0.47619047619047616 0.047619047619047616 12 | OMIM:309580 Orphanet:93971 0.2 0.2 0.4 0.2 13 | OMIM:309580 Orphanet:93972 0.2 0.2 0.4 0.2 14 | OMIM:309580 Orphanet:93973 0.23809523809523808 0.23809523809523808 0.47619047619047616 0.047619047619047616 15 | OMIM:309580 Orphanet:93974 0.25 0.25 0.375 0.125 16 | OMIM:309580 Orphanet:93975 0.25 0.25 0.375 0.125 17 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/cases/xlid.obo: -------------------------------------------------------------------------------- 1 | format-version: 1.2 2 | ontology: doid 3 | subsetdef: DO_MGI_slim "DO_MGI_slim" 4 | subsetdef: DO_cancer_slim "DO cancer slim" 5 | subsetdef: DO_rare_slim "DO_rare_slim" 6 | subsetdef: GOLD "GOLD" 7 | subsetdef: MEDIC-Slim "MEDIC (disease) slim" 8 | subsetdef: NCIthesaurus "NCIt" 9 | subsetdef: TopNodes_DOcancerslim "TopNodes_DOcancerslim" 10 | subsetdef: gram-negative_bacterial_infectious_disease "gram-negative bacterial infectious disease" 11 | subsetdef: gram-positive_bacterial_infectious_disease "gram-positive bacterial infectious disease" 12 | subsetdef: mesh_antislim "MESH antislim" 13 | subsetdef: sexually_transmitted_infectious_disease "sexually transmitted infectious disease" 14 | subsetdef: tick-borne_infectious_disease "tick-borne infectious disease" 15 | subsetdef: zoonotic_infectious_disease "zoonotic infectious disease" 16 | 17 | [Term] 18 | id: DOID:0060037 19 | name: developmental disorder of mental health 20 | namespace: disease_ontology 21 | def: "A disease of mental health that occur during a child's developmental period between birth and age 18 resulting in retarding of the child's psychological or physical development." [url:http://en.wikipedia.org/wiki/Developmental_disorders] 22 | is_a: DOID:150 ! disease of mental health 23 | 24 | [Term] 25 | id: DOID:0060038 26 | name: specific developmental disorder 27 | namespace: disease_ontology 28 | def: "A developmental disorder of mental health that categorizes specific learning disabilities and developmental disorders affecting coordination." [url:http://en.wikipedia.org/wiki/Specific_developmental_disorder] 29 | is_a: DOID:0060037 ! developmental disorder of mental health 30 | 31 | [Term] 32 | id: DOID:1059 33 | name: intellectual disability 34 | namespace: disease_ontology 35 | def: "A specific developmental disorder that involves significant limitations both in mental functioning and in adaptive behavior such as communicating, taking care of him or herself, and social skills." [url:http://www.aamr.org/content_96.cfm?navID=20, url:http://www.google.com/url?sa=t&source=web&cd=9&ved=0CGEQFjAI&url=http%3A%2F%2Fwww.nichcy.org%2FDisabilities%2FSpecific%2FPages%2FIntellectualDisability.aspx&rct=j&q=%20Search%20Intellectual%20Disability%3A%20Definition%2C%20Classification%2C%20and%20Systems%20of%20Supports%20&ei=_Y7dTJ-JKoX7lweUy837DA&usg=AFQjCNHf5WD4JW8kvTc901MQ6AUr_mRPpQ&sig2=sV1yzHR9plpkHZMXYtd8iA&cad=rja, url:http://www.nichcy.org/disabilities/specific/pages/intellectualdisability.aspx#WhatisID.aspx] 36 | comment: OMIM mapping submitted by NeuroDevNet. [LS]. 37 | synonym: "MENTAL RETARDATION, AUTOSOMAL RECESSIVE 15" EXACT [] 38 | synonym: "mental retardation" RELATED [] 39 | xref: MESH:D008607 40 | xref: NCIT:C84392 41 | xref: Orphanet:183757 42 | xref: Orphanet:87277 43 | xref: SCTID:154978008 44 | xref: SCTID:154979000 45 | xref: SCTID:1855002 46 | xref: SCTID:192157003 47 | xref: SCTID:192557008 48 | xref: SCTID:268732001 49 | xref: SCTID:91138005 50 | xref: UMLS:C0025362 51 | is_a: DOID:0060038 ! specific developmental disorder 52 | 53 | [Term] 54 | id: DOID:150 55 | name: disease of mental health 56 | namespace: disease_ontology 57 | def: "A disease that involves a psychological or behavioral pattern generally associated with subjective distress or disability that occurs in an individual, and which are not a part of normal development or culture." [url:http://en.wikipedia.org/wiki/Mental_disorder] 58 | xref: ICD10:F99 59 | xref: ICD10:F99-F99 60 | xref: MESH:D001523 61 | xref: NCIT:C2893 62 | xref: SCTID:154843007 63 | xref: SCTID:154971002 64 | xref: SCTID:154972009 65 | xref: SCTID:154980002 66 | xref: SCTID:192637001 67 | xref: SCTID:192639003 68 | xref: SCTID:74732009 69 | xref: UMLS:C0004936 70 | is_a: DOID:4 ! disease 71 | 72 | [Term] 73 | id: DOID:4 74 | name: disease 75 | namespace: disease_ontology 76 | def: "A disease is a disposition (i) to undergo pathological processes that (ii) exists in an organism because of one or more disorders in that organism." [url:http://ontology.buffalo.edu/medo/Disease_and_Diagnosis.pdf] 77 | xref: MESH:D004194 78 | xref: NCIT:C2991 79 | xref: Orphanet:182222 80 | xref: Orphanet:377788 81 | xref: Orphanet:98053 82 | xref: SCTID:64572001 83 | xref: UMLS:C0012634 84 | equivalent_to: Orphanet:C001 ! phenome 85 | 86 | [Term] 87 | id: DOID:630 88 | name: genetic disease 89 | namespace: disease_ontology 90 | def: "A disease that has_material_basis_in genetic variations in the human genome." [url:http://ghr.nlm.nih.gov/] 91 | xref: MESH:D030342 92 | xref: NCIT:C3101 93 | xref: Orphanet:377788 94 | xref: Orphanet:98053 95 | xref: SCTID:264530000 96 | xref: SCTID:32895009 97 | xref: UMLS:C0019247 98 | is_a: DOID:4 ! disease 99 | 100 | [Term] 101 | id: DOID:7 102 | name: disease of anatomical entity 103 | namespace: disease_ontology 104 | alt_id: DOID:1 105 | alt_id: DOID:2 106 | alt_id: DOID:5 107 | alt_id: DOID:71 108 | alt_id: DOID:72 109 | alt_id: DOID:8 110 | def: "A disease that manifests in a defined anatomical structure." [DO:wk,ls, http://www2.merriam-webster.com/cgi-bin/mwmednlm?book=Medical&va=anatomic] 111 | is_a: DOID:4 ! disease 112 | 113 | [Term] 114 | id: DOID:863 115 | name: nervous system disease 116 | namespace: disease_ontology 117 | def: "A disease of anatomical entity that is located_in the central nervous system or located_in the peripheral nervous system." [url:http://en.wikipedia.org/wiki/Nervous_system] 118 | synonym: "neurologic disease" EXACT [] 119 | synonym: "neurologic disorder" EXACT [] 120 | synonym: "neurological disease" EXACT [] 121 | synonym: "neurological disorder" EXACT [] 122 | xref: ICD10:G00-G99 123 | xref: ICD10:G98 124 | xref: ICD10:G98.8 125 | xref: ICD9:349.9 126 | xref: MESH:D009422 127 | xref: NCIT:C26835 128 | xref: Orphanet:98006 129 | xref: SCTID:118940003 130 | xref: SCTID:154981003 131 | xref: SCTID:155262005 132 | xref: SCTID:192641002 133 | xref: SCTID:267679005 134 | xref: SCTID:286946008 135 | xref: UMLS:C0027765 136 | is_a: DOID:7 ! disease of anatomical entity 137 | 138 | [Term] 139 | id: MESH:C537457 140 | name: Mental retardation-hypotonic facies syndrome, x-linked, 1 141 | namespace: disease_ontology 142 | synonym: "Carpenter-Waziri syndrome" RELATED [] 143 | synonym: "Chudley Lowry Hoar syndrome" RELATED [] 144 | synonym: "Chudley mental retardation syndrome" RELATED [] 145 | synonym: "Chudley syndrome 1" RELATED [] 146 | synonym: "Chudley-Lowry Syndrome" RELATED [] 147 | synonym: "Holmes-Gang syndrome" RELATED [] 148 | synonym: "Juberg Marsidi syndrome" RELATED [] 149 | synonym: "Juberg-Marsidi Mental Retardation Syndrome" RELATED [] 150 | synonym: "Juberg-Marsidi syndrome" RELATED [] 151 | synonym: "Mental Retradation, X-linked with Growth Delay, Deafness, Microgenitalism" RELATED [] 152 | synonym: "Mental retardation, x-linked, with growth retardation, deafness, and microgenitalism" RELATED [] 153 | synonym: "Smith-fineman-myers syndrome 1" RELATED [] 154 | synonym: "X-Linked Mental Retardation-Hypotonic Facies Syndrome" RELATED [] 155 | synonym: "X-linked hypogonadism gynecomastia mental retardation" RELATED [] 156 | xref: OMIM:309580 157 | is_a: MESH:D003638 ! Deafness 158 | is_a: MESH:D006130 ! Growth Disorders 159 | is_a: MESH:D007006 ! Hypogonadism 160 | is_a: MESH:D038901 ! Mental Retardation, X-Linked 161 | 162 | [Term] 163 | id: MESH:D001523 164 | name: Mental Disorders 165 | namespace: disease_ontology 166 | def: "Psychiatric illness or diseases manifested by breakdowns in the adaptational process expressed primarily as abnormalities of thought, feeling, and behavior producing either distress or impairment of function." [MESH:D001523] 167 | subset: MEDIC-Slim ! MEDIC (disease) slim 168 | synonym: "Behavior Disorders" RELATED [] 169 | synonym: "Diagnosis, Psychiatric" RELATED [] 170 | synonym: "Disorder, Mental" RELATED [] 171 | synonym: "Disorder, Severe Mental" RELATED [] 172 | synonym: "Disorders, Behavior" RELATED [] 173 | synonym: "Disorders, Mental" RELATED [] 174 | synonym: "Disorders, Severe Mental" RELATED [] 175 | synonym: "Mental Disorder" RELATED [] 176 | synonym: "Mental Disorder, Severe" RELATED [] 177 | synonym: "Mental Disorders, Severe" RELATED [] 178 | synonym: "Psychiatric Diagnosis" RELATED [] 179 | synonym: "Severe Mental Disorder" RELATED [] 180 | synonym: "Severe Mental Disorders" RELATED [] 181 | 182 | [Term] 183 | id: MESH:D003638 184 | name: Deafness 185 | namespace: disease_ontology 186 | def: "A general term for the complete loss of the ability to hear from both ears." [MESH:D003638] 187 | synonym: "Acquired Deafness" RELATED [] 188 | synonym: "Bilateral Deafness" RELATED [] 189 | synonym: "Complete Hearing Loss" RELATED [] 190 | synonym: "Deaf Mutism" RELATED [] 191 | synonym: "Deaf-Mutism" RELATED [] 192 | synonym: "Deafness, Acquired" RELATED [] 193 | synonym: "Deafness, Bilateral" RELATED [] 194 | synonym: "Deafness, Prelingual" RELATED [] 195 | synonym: "Extreme Hearing Loss" RELATED [] 196 | synonym: "Hearing Loss, Complete" RELATED [] 197 | synonym: "Hearing Loss, Extreme" RELATED [] 198 | synonym: "Prelingual Deafness" RELATED [] 199 | is_a: MESH:D034381 ! Hearing Loss 200 | 201 | [Term] 202 | id: MESH:D004427 203 | name: Ear Diseases 204 | namespace: disease_ontology 205 | def: "Pathological processes of the ear, the hearing, and the equilibrium system of the body." [MESH:D004427] 206 | synonym: "Disease, Ear" RELATED [] 207 | synonym: "Disease, Otologic" RELATED [] 208 | synonym: "Disease, Otological" RELATED [] 209 | synonym: "Diseases, Ear" RELATED [] 210 | synonym: "Diseases, Otologic" RELATED [] 211 | synonym: "Diseases, Otological" RELATED [] 212 | synonym: "Ear Disease" RELATED [] 213 | synonym: "Otologic Disease" RELATED [] 214 | synonym: "Otologic Diseases" RELATED [] 215 | synonym: "Otological Disease" RELATED [] 216 | synonym: "Otological Diseases" RELATED [] 217 | is_a: MESH:D010038 ! Otorhinolaryngologic Diseases 218 | 219 | [Term] 220 | id: MESH:D004700 221 | name: Endocrine System Diseases 222 | namespace: disease_ontology 223 | def: "Pathological processes of the ENDOCRINE GLANDS, and diseases resulting from abnormal level of available HORMONES." [MESH:D004700] 224 | subset: MEDIC-Slim ! MEDIC (disease) slim 225 | synonym: "Disease, Endocrine" RELATED [] 226 | synonym: "Disease, Endocrine System" RELATED [] 227 | synonym: "Diseases of Endocrine System" RELATED [] 228 | synonym: "Diseases, Endocrine" RELATED [] 229 | synonym: "Diseases, Endocrine System" RELATED [] 230 | synonym: "Endocrine Disease" RELATED [] 231 | synonym: "Endocrine Diseases" RELATED [] 232 | synonym: "Endocrine System Disease" RELATED [] 233 | synonym: "System Disease, Endocrine" RELATED [] 234 | synonym: "System Diseases, Endocrine" RELATED [] 235 | 236 | [Term] 237 | id: MESH:D006058 238 | name: Gonadal Disorders 239 | namespace: disease_ontology 240 | def: "Pathological processes of the OVARIES or the TESTES." [MESH:D006058] 241 | synonym: "Disorder, Gonadal" RELATED [] 242 | synonym: "Disorders, Gonadal" RELATED [] 243 | synonym: "Gonadal Disorder" RELATED [] 244 | is_a: MESH:D004700 ! Endocrine System Diseases 245 | 246 | [Term] 247 | id: MESH:D006130 248 | name: Growth Disorders 249 | namespace: disease_ontology 250 | def: "Deviations from the average values for a specific age and sex in any or all of the following: height, weight, skeletal proportions, osseous development, or maturation of features. Included here are both acceleration and retardation of growth." [MESH:D006130] 251 | synonym: "Disorder, Growth" RELATED [] 252 | synonym: "Growth Disorder" RELATED [] 253 | synonym: "Growth, Stunted" RELATED [] 254 | synonym: "Stunted Growth" RELATED [] 255 | synonym: "Stunting" RELATED [] 256 | synonym: "Stuntings" RELATED [] 257 | 258 | [Term] 259 | id: MESH:D006311 260 | name: Hearing Disorders 261 | namespace: disease_ontology 262 | def: "Conditions that impair the transmission of auditory impulses and information from the level of the ear to the temporal cortices, including the sensorineural pathways." [MESH:D006311] 263 | synonym: "Distorted Hearing" RELATED [] 264 | synonym: "Dysacusis" RELATED [] 265 | synonym: "Hearing Disorder" RELATED [] 266 | synonym: "Hearing, Distorted" RELATED [] 267 | synonym: "Paracousis" RELATED [] 268 | synonym: "Paracusis" RELATED [] 269 | is_a: MESH:D004427 ! Ear Diseases 270 | is_a: MESH:D012678 ! Sensation Disorders 271 | 272 | [Term] 273 | id: MESH:D007006 274 | name: Hypogonadism 275 | namespace: disease_ontology 276 | def: "Condition resulting from deficient gonadal functions, such as GAMETOGENESIS and the production of GONADAL STEROID HORMONES. It is characterized by delay in GROWTH, germ cell maturation, and development of secondary sex characteristics. Hypogonadism can be due to a deficiency of GONADOTROPINS (hypogonadotropic hypogonadism) or due to primary gonadal failure (hypergonadotropic hypogonadism)." [MESH:D007006] 277 | synonym: "Hypergonadotropic Hypogonadism" RELATED [] 278 | synonym: "Hypogonadism, Hypergonadotropic" RELATED [] 279 | synonym: "Hypogonadism, Hypogonadotropic" RELATED [] 280 | synonym: "Hypogonadism, Isolated Hypogonadotropic" RELATED [] 281 | synonym: "Hypogonadotropic Hypogonadism" RELATED [] 282 | is_a: MESH:D006058 ! Gonadal Disorders 283 | 284 | [Term] 285 | id: MESH:D008607 286 | name: Intellectual Disability 287 | namespace: disease_ontology 288 | def: "Subnormal intellectual functioning which originates during the developmental period. This has multiple potential etiologies, including genetic defects and perinatal insults. Intelligence quotient (IQ) scores are commonly used to determine whether an individual has an intellectual disability. IQ scores between 70 and 79 are in the borderline range. Scores below 67 are in the disabled range. (from Joynt, Clinical Neurology, 1992, Ch55, p28)" [MESH:D008607] 289 | synonym: "Deficiencies, Mental" RELATED [] 290 | synonym: "Deficiency, Mental" RELATED [] 291 | synonym: "Development Disorder, Intellectual" RELATED [] 292 | synonym: "Development Disorders, Intellectual" RELATED [] 293 | synonym: "Disabilities, Intellectual" RELATED [] 294 | synonym: "Disability, Intellectual" RELATED [] 295 | synonym: "Disorder, Intellectual Development" RELATED [] 296 | synonym: "Disorders, Intellectual Development" RELATED [] 297 | synonym: "Idiocy" RELATED [] 298 | synonym: "Intellectual Development Disorder" RELATED [] 299 | synonym: "Intellectual Development Disorders" RELATED [] 300 | synonym: "Intellectual Disabilities" RELATED [] 301 | synonym: "Mental Deficiencies" RELATED [] 302 | synonym: "Mental Deficiency" RELATED [] 303 | synonym: "Mental Retardation" RELATED [] 304 | synonym: "Mental Retardation, Psychosocial" RELATED [] 305 | synonym: "Mental Retardations, Psychosocial" RELATED [] 306 | synonym: "Psychosocial Mental Retardation" RELATED [] 307 | synonym: "Psychosocial Mental Retardations" RELATED [] 308 | synonym: "Retardation, Mental" RELATED [] 309 | synonym: "Retardation, Psychosocial Mental" RELATED [] 310 | synonym: "Retardations, Psychosocial Mental" RELATED [] 311 | is_a: MESH:D019954 ! Neurobehavioral Manifestations 312 | is_a: MESH:D065886 ! Neurodevelopmental Disorders 313 | 314 | [Term] 315 | id: MESH:D009358 316 | name: Congenital, Hereditary, and Neonatal Diseases and Abnormalities 317 | namespace: disease_ontology 318 | def: "Diseases existing at birth and often before birth, or that develop during the first month of life (INFANT, NEWBORN, DISEASES), regardless of causation. Of these diseases, those characterized by structural deformities are termed CONGENITAL ABNORMALITIES." [MESH:D009358] 319 | synonym: "Congenital Disorder" RELATED [] 320 | synonym: "Congenital Disorders" RELATED [] 321 | synonym: "Disorder, Congenital" RELATED [] 322 | synonym: "Disorders, Congenital" RELATED [] 323 | synonym: "Neonatal Diseases and Abnormalities" RELATED [] 324 | 325 | [Term] 326 | id: MESH:D009422 327 | name: Nervous System Diseases 328 | namespace: disease_ontology 329 | def: "Diseases of the central and peripheral nervous system. This includes disorders of the brain, spinal cord, cranial nerves, peripheral nerves, nerve roots, autonomic nervous system, neuromuscular junction, and muscle." [MESH:D009422] 330 | subset: MEDIC-Slim ! MEDIC (disease) slim 331 | synonym: "Disease, Nervous System" RELATED [] 332 | synonym: "Diseases, Nervous System" RELATED [] 333 | synonym: "Disorder, Nervous System" RELATED [] 334 | synonym: "Disorder, Neurologic" RELATED [] 335 | synonym: "Disorder, Neurological" RELATED [] 336 | synonym: "Disorders, Nervous System" RELATED [] 337 | synonym: "Disorders, Neurologic" RELATED [] 338 | synonym: "Disorders, Neurological" RELATED [] 339 | synonym: "Nervous System Disease" RELATED [] 340 | synonym: "Nervous System Disorder" RELATED [] 341 | synonym: "Nervous System Disorders" RELATED [] 342 | synonym: "Neurologic Disorder" RELATED [] 343 | synonym: "Neurologic Disorders" RELATED [] 344 | synonym: "Neurological Disorder" RELATED [] 345 | synonym: "Neurological Disorders" RELATED [] 346 | 347 | [Term] 348 | id: MESH:D009461 349 | name: Neurologic Manifestations 350 | namespace: disease_ontology 351 | def: "Clinical signs and symptoms caused by nervous system injury or dysfunction." [MESH:D009461] 352 | synonym: "Deficit, Focal Neurologic" RELATED [] 353 | synonym: "Deficit, Neurologic" RELATED [] 354 | synonym: "Deficits, Focal Neurologic" RELATED [] 355 | synonym: "Deficits, Neurologic" RELATED [] 356 | synonym: "Dysfunction, Neurologic" RELATED [] 357 | synonym: "Dysfunctions, Neurologic" RELATED [] 358 | synonym: "Finding, Neurologic" RELATED [] 359 | synonym: "Findings, Neurologic" RELATED [] 360 | synonym: "Focal Neurologic Deficit" RELATED [] 361 | synonym: "Focal Neurologic Deficits" RELATED [] 362 | synonym: "Manifestation, Neurologic" RELATED [] 363 | synonym: "Manifestation, Neurological" RELATED [] 364 | synonym: "Manifestations, Neurologic" RELATED [] 365 | synonym: "Manifestations, Neurological" RELATED [] 366 | synonym: "Neurologic Deficit" RELATED [] 367 | synonym: "Neurologic Deficit, Focal" RELATED [] 368 | synonym: "Neurologic Deficits" RELATED [] 369 | synonym: "Neurologic Deficits, Focal" RELATED [] 370 | synonym: "Neurologic Dysfunction" RELATED [] 371 | synonym: "Neurologic Dysfunctions" RELATED [] 372 | synonym: "Neurologic Finding" RELATED [] 373 | synonym: "Neurologic Findings" RELATED [] 374 | synonym: "Neurologic Manifestation" RELATED [] 375 | synonym: "Neurologic Sign" RELATED [] 376 | synonym: "Neurologic Signs" RELATED [] 377 | synonym: "Neurologic Signs and Symptoms" RELATED [] 378 | synonym: "Neurologic Symptom" RELATED [] 379 | synonym: "Neurologic Symptoms" RELATED [] 380 | synonym: "Neurological Manifestation" RELATED [] 381 | synonym: "Neurological Manifestations" RELATED [] 382 | synonym: "Sign, Neurologic" RELATED [] 383 | synonym: "Signs, Neurologic" RELATED [] 384 | synonym: "Symptom, Neurologic" RELATED [] 385 | synonym: "Symptoms, Neurologic" RELATED [] 386 | is_a: MESH:D009422 ! Nervous System Diseases 387 | 388 | [Term] 389 | id: MESH:D010038 390 | name: Otorhinolaryngologic Diseases 391 | namespace: disease_ontology 392 | def: "Pathological processes of the ear, the nose, and the throat, also known as the ENT diseases." [MESH:D010038] 393 | subset: MEDIC-Slim ! MEDIC (disease) slim 394 | synonym: "Disease, ENT" RELATED [] 395 | synonym: "Disease, Otolaryngologic" RELATED [] 396 | synonym: "Disease, Otolaryngological" RELATED [] 397 | synonym: "Disease, Otorhinolaryngologic" RELATED [] 398 | synonym: "Disease, Otorhinolaryngological" RELATED [] 399 | synonym: "Diseases, ENT" RELATED [] 400 | synonym: "Diseases, Otolaryngologic" RELATED [] 401 | synonym: "Diseases, Otolaryngological" RELATED [] 402 | synonym: "Diseases, Otorhinolaryngologic" RELATED [] 403 | synonym: "Diseases, Otorhinolaryngological" RELATED [] 404 | synonym: "ENT Disease" RELATED [] 405 | synonym: "ENT Diseases" RELATED [] 406 | synonym: "Otolaryngologic Disease" RELATED [] 407 | synonym: "Otolaryngologic Diseases" RELATED [] 408 | synonym: "Otolaryngological Disease" RELATED [] 409 | synonym: "Otolaryngological Diseases" RELATED [] 410 | synonym: "Otorhinolaryngologic Disease" RELATED [] 411 | synonym: "Otorhinolaryngological Disease" RELATED [] 412 | synonym: "Otorhinolaryngological Diseases" RELATED [] 413 | 414 | [Term] 415 | id: MESH:D012678 416 | name: Sensation Disorders 417 | namespace: disease_ontology 418 | def: "Disorders of the special senses (i.e., VISION; HEARING; TASTE; and SMELL) or somatosensory system (i.e., afferent components of the PERIPHERAL NERVOUS SYSTEM)." [MESH:D012678] 419 | synonym: "Sensation Disorder" RELATED [] 420 | synonym: "Senses Disorder, Special" RELATED [] 421 | synonym: "Senses Disorders, Special" RELATED [] 422 | synonym: "Sensory Disorder" RELATED [] 423 | synonym: "Sensory Disorders" RELATED [] 424 | synonym: "Special Senses Disorder" RELATED [] 425 | synonym: "Special Senses Disorders" RELATED [] 426 | is_a: MESH:D009461 ! Neurologic Manifestations 427 | 428 | [Term] 429 | id: MESH:D019636 430 | name: Neurodegenerative Diseases 431 | namespace: disease_ontology 432 | def: "Hereditary and sporadic conditions which are characterized by progressive nervous system dysfunction. These disorders are often associated with atrophy of the affected central or peripheral nervous system structures." [MESH:D019636] 433 | synonym: "Degenerative Condition, Neurologic" RELATED [] 434 | synonym: "Degenerative Conditions, Neurologic" RELATED [] 435 | synonym: "Degenerative Diseases, Central Nervous System" RELATED [] 436 | synonym: "Degenerative Diseases, Nervous System" RELATED [] 437 | synonym: "Degenerative Diseases, Neurologic" RELATED [] 438 | synonym: "Degenerative Diseases, Spinal Cord" RELATED [] 439 | synonym: "Degenerative Neurologic Disease" RELATED [] 440 | synonym: "Degenerative Neurologic Diseases" RELATED [] 441 | synonym: "Degenerative Neurologic Disorder" RELATED [] 442 | synonym: "Degenerative Neurologic Disorders" RELATED [] 443 | synonym: "Nervous System Degenerative Diseases" RELATED [] 444 | synonym: "Neurodegenerative Disease" RELATED [] 445 | synonym: "Neurodegenerative Disorder" RELATED [] 446 | synonym: "Neurodegenerative Disorders" RELATED [] 447 | synonym: "Neurologic Degenerative Condition" RELATED [] 448 | synonym: "Neurologic Degenerative Conditions" RELATED [] 449 | synonym: "Neurologic Degenerative Disease" RELATED [] 450 | synonym: "Neurologic Degenerative Diseases" RELATED [] 451 | synonym: "Neurologic Disease, Degenerative" RELATED [] 452 | synonym: "Neurologic Diseases, Degenerative" RELATED [] 453 | synonym: "Neurologic Disorder, Degenerative" RELATED [] 454 | synonym: "Neurologic Disorders, Degenerative" RELATED [] 455 | is_a: MESH:D009422 ! Nervous System Diseases 456 | 457 | [Term] 458 | id: MESH:D019954 459 | name: Neurobehavioral Manifestations 460 | namespace: disease_ontology 461 | def: "Signs and symptoms of higher cortical dysfunction caused by organic conditions. These include certain behavioral alterations and impairments of skills involved in the acquisition, processing, and utilization of knowledge or information." [MESH:D019954] 462 | synonym: "Cognitive Manifestation" RELATED [] 463 | synonym: "Cognitive Manifestations" RELATED [] 464 | synonym: "Cognitive Symptom" RELATED [] 465 | synonym: "Cognitive Symptoms" RELATED [] 466 | synonym: "Manifestation, Cognitive" RELATED [] 467 | synonym: "Manifestation, Neurobehavioral" RELATED [] 468 | synonym: "Manifestations, Cognitive" RELATED [] 469 | synonym: "Manifestations, Neurobehavioral" RELATED [] 470 | synonym: "Neurobehavioral Manifestation" RELATED [] 471 | synonym: "Neurobehavioral Signs and Symptoms" RELATED [] 472 | synonym: "Signs and Symptoms, Neurobehavioral" RELATED [] 473 | synonym: "Symptom, Cognitive" RELATED [] 474 | synonym: "Symptoms, Cognitive" RELATED [] 475 | is_a: MESH:D009461 ! Neurologic Manifestations 476 | 477 | [Term] 478 | id: MESH:D020271 479 | name: Heredodegenerative Disorders, Nervous System 480 | namespace: disease_ontology 481 | def: "Inherited disorders characterized by progressive atrophy and dysfunction of anatomically or physiologically related neurologic systems." [MESH:D020271] 482 | synonym: "Degenerative Disease, Nervous System, Hereditary" RELATED [] 483 | synonym: "Degenerative Hereditary Diseases, Nervous System" RELATED [] 484 | synonym: "Degenerative Hereditary Disorders, Nervous System" RELATED [] 485 | synonym: "Disease, Hereditary Neurodegenerative" RELATED [] 486 | synonym: "Disease, Neurodegenerative Hereditary" RELATED [] 487 | synonym: "Diseases, Hereditary Neurodegenerative" RELATED [] 488 | synonym: "Diseases, Neurodegenerative Hereditary" RELATED [] 489 | synonym: "Hereditary Degenerative Disorders, Nervous System" RELATED [] 490 | synonym: "Hereditary Disease, Neurodegenerative" RELATED [] 491 | synonym: "Hereditary Diseases, Neurodegenerative" RELATED [] 492 | synonym: "Hereditary Neurodegenerative Disease" RELATED [] 493 | synonym: "Hereditary Neurodegenerative Diseases" RELATED [] 494 | synonym: "Hereditary-Degenerative Disorders, Nervous System" RELATED [] 495 | synonym: "Nervous System Degenerative Hereditary Diseases" RELATED [] 496 | synonym: "Nervous System Diseases, Degenerative, Hereditary" RELATED [] 497 | synonym: "Nervous System Hereditary Degenerative Diseases" RELATED [] 498 | synonym: "Neurodegenerative Disease, Hereditary" RELATED [] 499 | synonym: "Neurodegenerative Diseases, Hereditary" RELATED [] 500 | synonym: "Neurodegenerative Hereditary Disease" RELATED [] 501 | synonym: "Neurodegenerative Hereditary Diseases" RELATED [] 502 | is_a: MESH:D019636 ! Neurodegenerative Diseases 503 | is_a: MESH:D030342 ! Genetic Diseases, Inborn 504 | 505 | [Term] 506 | id: MESH:D030342 507 | name: Genetic Diseases, Inborn 508 | namespace: disease_ontology 509 | def: "Diseases that are caused by genetic mutations present during embryo or fetal development, although they may be observed later in life. The mutations may be inherited from a parent's genome or they may be acquired in utero." [MESH:D030342] 510 | subset: MEDIC-Slim ! MEDIC (disease) slim 511 | synonym: "Defect, Single-Gene" RELATED [] 512 | synonym: "Defects, Single-Gene" RELATED [] 513 | synonym: "Disease, Hereditary" RELATED [] 514 | synonym: "Disease, Inborn Genetic" RELATED [] 515 | synonym: "Diseases, Hereditary" RELATED [] 516 | synonym: "Diseases, Inborn Genetic" RELATED [] 517 | synonym: "Genetic Disease, Inborn" RELATED [] 518 | synonym: "Hereditary Disease" RELATED [] 519 | synonym: "Hereditary Diseases" RELATED [] 520 | synonym: "Inborn Genetic Disease" RELATED [] 521 | synonym: "Inborn Genetic Diseases" RELATED [] 522 | synonym: "Single Gene Defects" RELATED [] 523 | synonym: "Single-Gene Defect" RELATED [] 524 | synonym: "Single-Gene Defects" RELATED [] 525 | is_a: MESH:D009358 ! Congenital, Hereditary, and Neonatal Diseases and Abnormalities 526 | 527 | [Term] 528 | id: MESH:D034381 529 | name: Hearing Loss 530 | namespace: disease_ontology 531 | def: "A general term for the complete or partial loss of the ability to hear from one or both ears." [MESH:D034381] 532 | synonym: "Hearing Impairment" RELATED [] 533 | synonym: "Hypoacuses" RELATED [] 534 | synonym: "Hypoacusis" RELATED [] 535 | synonym: "Loss, Hearing" RELATED [] 536 | is_a: MESH:D006311 ! Hearing Disorders 537 | 538 | [Term] 539 | id: MESH:D038901 540 | name: Mental Retardation, X-Linked 541 | namespace: disease_ontology 542 | def: "A class of genetic disorders resulting in INTELLECTUAL DISABILITY that is associated either with mutations of GENES located on the X CHROMOSOME or aberrations in the structure of the X chromosome (SEX CHROMOSOME ABERRATIONS)." [MESH:D038901] 543 | synonym: "Mental Retardation, X Linked" RELATED [] 544 | synonym: "Retardation, X-Linked Mental" RELATED [] 545 | synonym: "X Linked Mental Retardation" RELATED [] 546 | synonym: "X Linked Mental Retardation Disorders" RELATED [] 547 | synonym: "X Linked Mental Retardation Syndromes" RELATED [] 548 | synonym: "X-Linked Mental Retardation" RELATED [] 549 | synonym: "X-Linked Mental Retardation Disorders" RELATED [] 550 | synonym: "X-Linked Mental Retardation Syndromes" RELATED [] 551 | synonym: "X-Linked Mental Retardations" RELATED [] 552 | is_a: MESH:D008607 ! Intellectual Disability 553 | is_a: MESH:D020271 ! Heredodegenerative Disorders, Nervous System 554 | is_a: MESH:D040181 ! Genetic Diseases, X-Linked 555 | 556 | [Term] 557 | id: MESH:D040181 558 | name: Genetic Diseases, X-Linked 559 | namespace: disease_ontology 560 | def: "Genetic diseases that are linked to gene mutations on the X CHROMOSOME in humans (X CHROMOSOME, HUMAN) or the X CHROMOSOME in other species. Included here are animal models of human X-linked diseases." [MESH:D040181] 561 | synonym: "Disease, X-Linked Genetic" RELATED [] 562 | synonym: "Diseases, X-Linked Genetic" RELATED [] 563 | synonym: "Genetic Disease, X-Linked" RELATED [] 564 | synonym: "Genetic Diseases, X Chromosome Linked" RELATED [] 565 | synonym: "Genetic Diseases, X Linked" RELATED [] 566 | synonym: "Genetic Diseases, X-Chromosome Linked" RELATED [] 567 | synonym: "X Linked Genetic Diseases" RELATED [] 568 | synonym: "X-Linked Genetic Disease" RELATED [] 569 | synonym: "X-Linked Genetic Diseases" RELATED [] 570 | is_a: MESH:D030342 ! Genetic Diseases, Inborn 571 | 572 | [Term] 573 | id: MESH:D065886 574 | name: Neurodevelopmental Disorders 575 | namespace: disease_ontology 576 | def: "These are a group of conditions with onset in the developmental period. The disorders typically manifest early in development, often before the child enters grade school, and are characterized by developmental deficits that produce impairments of personal, social, academic, or occupational functioning. (From DSM-V)." [MESH:D065886] 577 | synonym: "Child Mental Disorder" RELATED [] 578 | synonym: "Child Mental Disorders" RELATED [] 579 | synonym: "Disorder, Child Mental" RELATED [] 580 | synonym: "Disorder, Neurodevelopmental" RELATED [] 581 | synonym: "Disorders Usually Diagnosed in Infancy, Childhood or Adolescence" RELATED [] 582 | synonym: "Disorders, Child Mental" RELATED [] 583 | synonym: "Disorders, Neurodevelopmental" RELATED [] 584 | synonym: "Mental Disorder, Child" RELATED [] 585 | synonym: "Mental Disorders Diagnosed in Childhood" RELATED [] 586 | synonym: "Mental Disorders, Child" RELATED [] 587 | synonym: "Neurodevelopmental Disorder" RELATED [] 588 | is_a: MESH:D001523 ! Mental Disorders 589 | 590 | [Term] 591 | id: OMIM:309580 592 | name: Mental Retardation-Hypotonic Facies Syndrome, X-Linked, 1 593 | namespace: disease_ontology 594 | def: "The term 'X-linked mental retardation-hypotonic facies syndrome' comprises several syndromes previously reported separately. These include Juberg-Marsidi, Carpenter-Waziri, Holmes-Gang, and Smith-Fineman-Myers syndromes as well as 1 family with X-linked mental retardation with spastic paraplegia. All these syndromes were found to be caused by mutation in the XH2 gene and are characterized primarily by severe mental retardation, dysmorphic facies, and a highly skewed X-inactivation pattern in carrier women (\{2:Abidi et al., 2005\}). Other more variable features include hypogonadism, deafness, renal anomalies, and mild skeletal defects.nnX-linked alpha-thalassemia/mental retardation syndrome (ATR-X; OMIM:301040) is an allelic disorder with a similar phenotype with the addition of alpha-thalassemia and Hb H inclusion bodies in erythrocytes." [] 595 | synonym: "Carpenter-Waziri Syndrome" RELATED [] 596 | synonym: "Chudley-Lowry Syndrome" RELATED [] 597 | synonym: "Holmes-Gang Syndrome" RELATED [] 598 | synonym: "Juberg-Marsidi Syndrome" RELATED [] 599 | synonym: "MENTAL RETARDATION-HYPOTONIC FACIES SYNDROME, X-LINKED, 1; MRXHF1" RELATED [] 600 | synonym: "MRXHF1" RELATED [] 601 | synonym: "Mental Retardation, X-Linked, With Growth Retardation, Deafness, and Microgenitalism" RELATED [] 602 | synonym: "Sfms" RELATED [] 603 | synonym: "Smith-Fineman-Myers Syndrome 1" RELATED [] 604 | synonym: "Xlmr-Hypotonic Facies Syndrome" RELATED [] 605 | is_a: DOID:4 ! disease 606 | 607 | [Term] 608 | id: Orphanet:101433 609 | name: Rare urogenital disease 610 | namespace: disease_ontology 611 | subset: Orphanet:377794 612 | is_a: Orphanet:C001 ! phenome 613 | 614 | [Term] 615 | id: Orphanet:102283 616 | name: Multiple congenital anomalies/dysmorphic syndrome-intellectual disability 617 | namespace: disease_ontology 618 | subset: Orphanet:377794 619 | synonym: "MCA/MR" EXACT [] 620 | synonym: "Multiple congenital anomalies-intellectual disability with or without dysmorphism" EXACT [] 621 | is_a: Orphanet:183530 ! Rare genetic developmental defect during embryogenesis 622 | is_a: Orphanet:68341 ! Multiple congenital anomalies/dysmorphic syndrome 623 | 624 | [Term] 625 | id: Orphanet:102369 626 | name: Rare intellectual disability with developmental anomaly 627 | namespace: disease_ontology 628 | subset: Orphanet:377794 629 | synonym: "Syndromic intellectual disability" EXACT [] 630 | synonym: "Syndromic mental deficiency" EXACT [] 631 | is_a: Orphanet:87277 ! Rare intellectual disability 632 | 633 | [Term] 634 | id: Orphanet:156619 635 | name: Rare genetic urogenital disease 636 | namespace: disease_ontology 637 | subset: Orphanet:377794 638 | is_a: Orphanet:C001 ! phenome 639 | 640 | [Term] 641 | id: Orphanet:165707 642 | name: Syndromic urogenital tract malformation 643 | namespace: disease_ontology 644 | subset: Orphanet:377794 645 | is_a: Orphanet:156619 ! Rare genetic urogenital disease 646 | is_a: Orphanet:83001 ! Urogenital tract malformation 647 | 648 | [Term] 649 | id: Orphanet:183530 650 | name: Rare genetic developmental defect during embryogenesis 651 | namespace: disease_ontology 652 | subset: Orphanet:377794 653 | is_a: Orphanet:C001 ! phenome 654 | 655 | [Term] 656 | id: Orphanet:183757 657 | name: Rare genetic intellectual disability 658 | namespace: disease_ontology 659 | subset: Orphanet:377794 660 | is_a: DOID:1059 ! intellectual disability 661 | is_a: DOID:630 ! genetic disease 662 | is_a: Orphanet:71859 ! Rare genetic neurological disorder 663 | 664 | [Term] 665 | id: Orphanet:183763 666 | name: Rare genetic intellectual disability with developmental anomaly 667 | namespace: disease_ontology 668 | subset: Orphanet:377794 669 | is_a: Orphanet:183757 ! Rare genetic intellectual disability 670 | 671 | [Term] 672 | id: Orphanet:263355 673 | name: ATR-X-related syndrome 674 | namespace: disease_ontology 675 | subset: Orphanet:377794 676 | is_a: Orphanet:102283 ! Multiple congenital anomalies/dysmorphic syndrome-intellectual disability 677 | is_a: Orphanet:98464 ! X-linked syndromic intellectual disability 678 | 679 | [Term] 680 | id: Orphanet:68341 681 | name: Multiple congenital anomalies/dysmorphic syndrome 682 | namespace: disease_ontology 683 | subset: Orphanet:377794 684 | is_a: Orphanet:93890 ! Rare developmental defect during embryogenesis 685 | 686 | [Term] 687 | id: Orphanet:71859 688 | name: Rare genetic neurological disorder 689 | namespace: disease_ontology 690 | subset: Orphanet:377794 691 | is_a: Orphanet:C001 ! phenome 692 | 693 | [Term] 694 | id: Orphanet:73220 695 | name: X-linked intellectual disability - hypotonic face 696 | namespace: disease_ontology 697 | subset: Orphanet:377794 698 | xref: OMIM:309580 699 | is_a: Orphanet:263355 ! ATR-X-related syndrome 700 | 701 | [Term] 702 | id: Orphanet:83001 703 | name: Urogenital tract malformation 704 | namespace: disease_ontology 705 | subset: Orphanet:377794 706 | is_a: Orphanet:101433 ! Rare urogenital disease 707 | is_a: Orphanet:93890 ! Rare developmental defect during embryogenesis 708 | 709 | [Term] 710 | id: Orphanet:87277 711 | name: Rare intellectual disability 712 | namespace: disease_ontology 713 | subset: Orphanet:377794 714 | is_a: DOID:1059 ! intellectual disability 715 | is_a: Orphanet:98006 ! Rare neurologic disease 716 | 717 | [Term] 718 | id: Orphanet:93890 719 | name: Rare developmental defect during embryogenesis 720 | namespace: disease_ontology 721 | subset: Orphanet:377794 722 | synonym: "Malformation syndrome" EXACT [] 723 | is_a: Orphanet:C001 ! phenome 724 | 725 | [Term] 726 | id: Orphanet:93970 727 | name: Holmes-Gang syndrome 728 | namespace: disease_ontology 729 | def: "Holmes-Gang syndrome is an X-linked mental retardation (XLMR) syndrome belonging to the group of conditions characterised by the association of intellectual deficit with hypotonic facies (Mental retardation, X-linked-hypotonic facies; see this term)." [] 730 | subset: Orphanet:377789 731 | xref: ICD10:Q87.0 732 | xref: OMIM:309580 733 | is_a: Orphanet:73220 ! X-linked intellectual disability - hypotonic face 734 | 735 | [Term] 736 | id: Orphanet:93971 737 | name: Chudley-Lowry-Hoar syndrome 738 | namespace: disease_ontology 739 | def: "Chudley-Lowry syndrome is an X-linked mental retardation (XLMR) syndrome belonging to the group of conditions characterised by the association of intellectual deficit with hypotonic facies (Mental retardation-hypotonic facies; see this term)." [] 740 | subset: Orphanet:377789 741 | synonym: "Chudley-Lowry syndrome" EXACT [] 742 | xref: OMIM:309580 743 | is_a: Orphanet:73220 ! X-linked intellectual disability - hypotonic face 744 | 745 | [Term] 746 | id: Orphanet:93972 747 | name: Juberg-Marsidi syndrome 748 | namespace: disease_ontology 749 | subset: Orphanet:377789 750 | xref: MESH:C537457 751 | xref: OMIM:309580 752 | xref: UMLS:C0796003 753 | is_a: Orphanet:165707 ! Syndromic urogenital tract malformation 754 | is_a: Orphanet:73220 ! X-linked intellectual disability - hypotonic face 755 | 756 | [Term] 757 | id: Orphanet:93973 758 | name: Carpenter-Waziri syndrome 759 | namespace: disease_ontology 760 | def: "Carpenter-Waziri syndrome is an X-linked mental retardation (XLMR) syndrome belonging to the group of conditions characterised by the association of intellectual deficit with hypotonic facies (Mental retardation, X-linked-hypotonic facies; see this term)." [] 761 | subset: Orphanet:377789 762 | xref: OMIM:309580 763 | is_a: Orphanet:73220 ! X-linked intellectual disability - hypotonic face 764 | 765 | [Term] 766 | id: Orphanet:93974 767 | name: Smith-Fineman-Myers syndrome 768 | namespace: disease_ontology 769 | def: "Smith-Fineman-Myers syndrome (SFMS) is an X-linked mental retardation (XLMR) syndrome belonging to the group of conditions characterised by the association of intellectual deficit with hypotonic facies (Mental retardation, X-linked-hypotonic facies; see this term)." [] 770 | subset: Orphanet:377789 771 | xref: OMIM:309580 772 | is_a: Orphanet:73220 ! X-linked intellectual disability - hypotonic face 773 | 774 | [Term] 775 | id: Orphanet:93975 776 | name: Renier-Gabreels-Jasper syndrome 777 | namespace: disease_ontology 778 | def: "Renier-Gabreels-Jasper syndrome is an X-linked mental retardation (XLMR) syndrome belonging to the group of conditions characterised by the association of intellectual deficit with hypotonic facies (Mental retardation, X-linked-hypotonic facies; see this term)." [] 779 | subset: Orphanet:377789 780 | xref: OMIM:309580 781 | is_a: Orphanet:73220 ! X-linked intellectual disability - hypotonic face 782 | 783 | [Term] 784 | id: Orphanet:98006 785 | name: Rare neurologic disease 786 | namespace: disease_ontology 787 | subset: Orphanet:377794 788 | synonym: "Rare nervous system disease" EXACT [] 789 | is_a: DOID:863 ! nervous system disease 790 | is_a: Orphanet:C001 ! phenome 791 | 792 | [Term] 793 | id: Orphanet:98464 794 | name: X-linked syndromic intellectual disability 795 | namespace: disease_ontology 796 | subset: Orphanet:377794 797 | is_a: Orphanet:102369 ! Rare intellectual disability with developmental anomaly 798 | is_a: Orphanet:183763 ! Rare genetic intellectual disability with developmental anomaly 799 | 800 | [Term] 801 | id: Orphanet:C001 802 | name: phenome 803 | namespace: disease_ontology 804 | def: "A set of phenotypes expressed at the cell, tissue, organ or organism level. It describes the \"physical totality of all traits of an organism or of one of its subsystems\" (Mahner and Kary, 1997)." [] 805 | 806 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/clique-test.obo: -------------------------------------------------------------------------------- 1 | ontology: x 2 | remark: fake ontology. fake OMIM IDs in flat hierarchy. Two additional hierarchies, X and Y 3 | 4 | [Term] 5 | id: X:root 6 | 7 | [Term] 8 | id: X:1 9 | name: x1 10 | is_a: X:root 11 | 12 | [Term] 13 | id: X:2 14 | is_a: X:root 15 | name: "x2" 16 | 17 | [Term] 18 | id: X:3 19 | is_a: X:root 20 | 21 | [Term] 22 | id: X:1a 23 | is_a: X:1 24 | 25 | [Term] 26 | id: X:1b 27 | is_a: X:1 28 | 29 | [Term] 30 | id: X:2a 31 | is_a: X:2 32 | 33 | [Term] 34 | id: X:2b 35 | is_a: X:2 36 | 37 | [Term] 38 | id: Y:root 39 | 40 | [Term] 41 | id: Y:1 42 | is_a: Y:root 43 | 44 | [Term] 45 | id: Y:2 46 | is_a: Y:root 47 | 48 | [Term] 49 | id: Y:1a 50 | is_a: Y:1 51 | 52 | [Term] 53 | id: Y:1b 54 | is_a: Y:1 55 | 56 | [Term] 57 | id: Y:2a 58 | is_a: Y:2 59 | 60 | [Term] 61 | id: Y:2b 62 | is_a: Y:2 63 | 64 | [Term] 65 | id: Y:2b1 66 | is_a: Y:2b 67 | 68 | [Term] 69 | id: Z:root 70 | 71 | [Term] 72 | id: Z:1 73 | is_a: Z:root 74 | 75 | [Term] 76 | id: Z:2 77 | is_a: Z:root 78 | 79 | [Term] 80 | id: Z:3 81 | is_a: Z:root 82 | 83 | [Term] 84 | id: Z:1a 85 | is_a: Z:1 86 | 87 | [Term] 88 | id: Z:1b 89 | is_a: Z:1 90 | 91 | [Term] 92 | id: Z:2a 93 | is_a: Z:2 94 | 95 | [Term] 96 | id: Z:2b 97 | is_a: Z:2 98 | 99 | [Term] 100 | id: Z:2b1 101 | is_a: Z:2b 102 | 103 | [Term] 104 | id: Z:2b1a 105 | is_a: Z:2b1 106 | 107 | [Term] 108 | id: Z:2b1b 109 | is_a: Z:2b1 110 | 111 | [Term] 112 | id: Z:2b1c 113 | is_a: Z:2b1 114 | 115 | [Term] 116 | id: OMIM:root 117 | 118 | [Term] 119 | id: OMIM:001 120 | is_a: OMIM:root 121 | 122 | [Term] 123 | id: OMIM:002 124 | is_a: OMIM:root 125 | 126 | [Term] 127 | id: OMIM:003 128 | is_a: OMIM:root 129 | 130 | [Term] 131 | id: OMIM:004 132 | is_a: OMIM:root 133 | 134 | [Term] 135 | id: OMIM:005 136 | is_a: OMIM:root 137 | 138 | [Term] 139 | id: OMIM:006 140 | is_a: OMIM:root 141 | 142 | [Term] 143 | id: OMIM:007 144 | is_a: OMIM:root 145 | 146 | [Term] 147 | id: OMIM:007 148 | is_a: OMIM:root 149 | 150 | [Term] 151 | id: OMIM:009 152 | is_a: OMIM:root 153 | 154 | [Term] 155 | id: OMIM:010 156 | is_a: OMIM:root 157 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/disjoint_test.obo: -------------------------------------------------------------------------------- 1 | ontology: x 2 | remark: X:1 and X:2 are two disjoint branches 3 | ontology: disjoint_test 4 | 5 | [Term] 6 | id: X:root 7 | 8 | [Term] 9 | id: X:1 10 | name: x1 11 | is_a: X:root 12 | 13 | [Term] 14 | id: X:2 15 | is_a: X:root 16 | name: "x2" 17 | disjoint_from: X:1 18 | 19 | [Term] 20 | id: X:2b 21 | is_a: X:2 22 | 23 | [Term] 24 | id: X:2c 25 | is_a: X:2 26 | 27 | [Term] 28 | id: X:1b 29 | is_a: X:1 30 | 31 | [Term] 32 | id: X:1c 33 | is_a: X:1 34 | 35 | [Term] 36 | id: X:1cA 37 | is_a: X:1c 38 | 39 | [Term] 40 | id: Y:root 41 | 42 | [Term] 43 | id: Y:1 44 | is_a: Y:root 45 | 46 | [Term] 47 | id: Y:1b 48 | is_a: Y:1 49 | 50 | [Term] 51 | id: Y:1c 52 | is_a: Y:1 53 | 54 | [Term] 55 | id: Y:2b 56 | is_a: Y:2 57 | 58 | [Term] 59 | id: Y:2c 60 | is_a: Y:2 61 | 62 | [Term] 63 | id: Y:1cA 64 | is_a: Y:1c 65 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.appender.console=org.apache.log4j.ConsoleAppender 2 | log4j.appender.console.layout=org.apache.log4j.PatternLayout 3 | log4j.appender.console.layout.ConversionPattern=%-5p %m%n 4 | #log4j.appender.console.layout.ConversionPattern=%d [%t] %-5p %c - %m%n 5 | log4j.logger.user=DEBUG 6 | #log4j.rootLogger=WARN, console 7 | log4j.rootLogger=INFO, console 8 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/nosol.obo: -------------------------------------------------------------------------------- 1 | ontology: nosol 2 | 3 | [Term] 4 | id: X:1 5 | disjoint_from: Y:1 6 | 7 | [Term] 8 | id: X:2 9 | is_a: X:1 10 | 11 | [Term] 12 | id: X:3 13 | is_a: X:2 14 | 15 | [Term] 16 | id: X:4 17 | is_a: X:3 18 | 19 | 20 | [Term] 21 | id: X:5 22 | is_a: X:4 23 | 24 | [Term] 25 | id: X:6 26 | is_a: X:5 27 | 28 | [Term] 29 | id: X:7 30 | is_a: X:6 31 | 32 | [Term] 33 | id: X:8 34 | is_a: X:7 35 | 36 | [Term] 37 | id: X:9 38 | is_a: X:8 39 | 40 | [Term] 41 | id: Y:1 42 | 43 | [Term] 44 | id: Y:2 45 | is_a: Y:1 46 | 47 | [Term] 48 | id: Y:3 49 | is_a: Y:2 50 | 51 | [Term] 52 | id: Y:4 53 | is_a: Y:3 54 | 55 | [Term] 56 | id: Y:5 57 | is_a: Y:4 58 | 59 | [Term] 60 | id: Y:6 61 | is_a: Y:5 62 | 63 | [Term] 64 | id: Y:7 65 | is_a: Y:6 66 | 67 | [Term] 68 | id: Y:8 69 | is_a: Y:7 70 | 71 | [Term] 72 | id: Y:9 73 | is_a: Y:8 74 | 75 | 76 | [Term] 77 | id: Z:1 78 | 79 | [Term] 80 | id: Z:2 81 | is_a: Z:1 82 | 83 | [Term] 84 | id: Z:3 85 | is_a: Z:2 86 | 87 | [Term] 88 | id: Z:4 89 | is_a: Z:3 90 | 91 | [Term] 92 | id: Z:5 93 | is_a: Z:4 94 | 95 | [Term] 96 | id: Z:6 97 | is_a: Z:5 98 | 99 | [Term] 100 | id: Z:7 101 | is_a: Z:6 102 | 103 | [Term] 104 | id: Z:8 105 | is_a: Z:7 106 | 107 | [Term] 108 | id: Z:9 109 | is_a: Z:8 110 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-asserted-subclass.tsv: -------------------------------------------------------------------------------- 1 | X:1 Z:1 0.0 0.0 1.0 0.0 2 | Y:1 Z:1 0.0 0.0 1.0 0.0 3 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-basic.tsv: -------------------------------------------------------------------------------- 1 | X:1 Y:1 0.2 0.2 0.6 0.1 2 | X:2 Y:2 0.1 0.1 0.75 0.05 3 | Y:2 Z:2 0.1 0.1 0.75 0.05 4 | Y:2 Z:2a 0.1 0.25 0.6 0.05 5 | Z:2a X:2 0.3 0.1 0.5 0.1 6 | Z:2b1a Y:2b1 0.2 0.2 0.5 0.1 7 | Z:2b1b Y:2b1 0.2 0.2 0.5 0.1 8 | Z:2b1c Y:2b1 0.19 0.2 0.51 0.1 9 | X:3 Z:3 0.1 0.1 0.8 0.0 10 | OMIM:001 Z:3 0.8 0.08 0.1 0.02 11 | OMIM:002 Z:3 0.8 0.08 0.1 0.02 12 | OMIM:003 Z:3 0.8 0.08 0.1 0.02 13 | OMIM:004 Z:3 0.8 0.08 0.1 0.02 14 | OMIM:005 Z:3 0.8 0.08 0.1 0.02 15 | OMIM:006 Z:3 0.8 0.08 0.1 0.02 16 | OMIM:007 Z:3 0.8 0.08 0.1 0.02 17 | OMIM:008 Z:3 0.8 0.08 0.1 0.02 18 | OMIM:009 Z:3 0.8 0.08 0.1 0.02 19 | OMIM:010 Z:3 0.8 0.08 0.1 0.02 20 | OMIM:010 X:3 0.2 0.2 0.6 0.1 21 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-disjoint.tsv: -------------------------------------------------------------------------------- 1 | Y:root X:root 0.15 0.15 0.50 0.20 2 | Y:1 X:1 0.05 0.05 0.85 0.05 3 | Y:2 X:2 0.05 0.05 0.85 0.05 4 | Y:2b X:2b 0.05 0.05 0.85 0.05 5 | Y:2c X:2c 0.05 0.05 0.85 0.05 6 | Y:1b X:1b 0.05 0.05 0.85 0.05 7 | Y:1c X:1c 0.15 0.15 0.40 0.30 8 | Y:1c X:2c 0.05 0.05 0.80 0.10 9 | Y:1cA X:1cA 0.05 0.05 0.85 0.05 10 | Y:1cA X:1c 0.50 0.15 0.20 0.15 11 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-false-positive.tsv: -------------------------------------------------------------------------------- 1 | X:1 Y:1 0.2 0.2 0.6 0.1 2 | OMIM:001 Z:2b1c 0.8 0.08 0.1 0.02 3 | OMIM:002 Z:2b1c 0.8 0.08 0.1 0.02 4 | OMIM:003 Z:2b1c 0.8 0.08 0.1 0.02 5 | OMIM:004 Z:2b1c 0.8 0.08 0.1 0.02 6 | OMIM:005 Z:2b1c 0.8 0.08 0.1 0.02 7 | OMIM:006 Z:2b1c 0.8 0.08 0.1 0.02 8 | OMIM:007 Z:2b1c 0.8 0.08 0.1 0.02 9 | OMIM:008 Z:2b1c 0.8 0.08 0.1 0.02 10 | OMIM:009 Z:2b1c 0.8 0.08 0.1 0.02 11 | OMIM:010 Z:2b1c 0.8 0.08 0.1 0.02 12 | OMIM:010 Z:2b1c 0.8 0.2 0.0 0.0 13 | OMIM:101 Z:2b1c 0.8 0.08 0.1 0.02 14 | OMIM:101 Y:1a1 0.8 0.08 0.1 0.02 15 | OMIM:102 Y:1a1 0.8 0.08 0.1 0.02 16 | OMIM:103 Y:1a1 0.8 0.08 0.1 0.02 17 | OMIM:104 Y:1a1 0.8 0.08 0.1 0.02 18 | OMIM:105 Y:1a1 0.8 0.08 0.1 0.02 19 | OMIM:106 Y:1a1 0.8 0.08 0.1 0.02 20 | OMIM:107 Y:1a1 0.8 0.08 0.1 0.02 21 | OMIM:108 Y:1a1 0.8 0.08 0.1 0.02 22 | OMIM:109 Y:1a1 0.8 0.08 0.1 0.02 23 | OMIM:110 Y:1a1 0.8 0.08 0.1 0.02 24 | OMIM:110 Y:1a1 0.8 0.2 0.0 0.0 25 | OMIM:101 X:2b 0.8 0.08 0.1 0.02 26 | OMIM:102 X:2b 0.8 0.08 0.1 0.02 27 | OMIM:103 X:2b 0.8 0.08 0.1 0.02 28 | OMIM:104 X:2b 0.8 0.08 0.1 0.02 29 | OMIM:105 X:2b 0.8 0.08 0.1 0.02 30 | OMIM:106 X:2b 0.8 0.08 0.1 0.02 31 | OMIM:107 X:2b 0.8 0.08 0.1 0.02 32 | OMIM:108 X:2b 0.8 0.08 0.1 0.02 33 | OMIM:109 X:2b 0.8 0.08 0.1 0.02 34 | OMIM:110 X:2b 0.8 0.08 0.1 0.02 35 | OMIM:110 X:2b 0.8 0.2 0.0 0.0 36 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-false-positive2.tsv: -------------------------------------------------------------------------------- 1 | X:1 Y:1 0.2 0.2 0.6 0.1 2 | OMIM:001 Z:2b1c 0.8 0.08 0.1 0.02 3 | OMIM:002 Z:2b1c 0.8 0.08 0.1 0.02 4 | OMIM:003 Z:2b1c 0.8 0.08 0.1 0.02 5 | OMIM:004 Z:2b1c 0.8 0.08 0.1 0.02 6 | OMIM:005 Z:2b1c 0.8 0.08 0.1 0.02 7 | OMIM:006 Z:2b1c 0.8 0.08 0.1 0.02 8 | OMIM:007 Z:2b1c 0.8 0.08 0.1 0.02 9 | OMIM:008 Z:2b1c 0.8 0.08 0.1 0.02 10 | OMIM:009 Z:2b1c 0.8 0.08 0.1 0.02 11 | OMIM:010 Z:2b1c 0.8 0.08 0.1 0.02 12 | OMIM:010 Z:2b1c 0.8 0.2 0.0 0.0 13 | OMIM:101 Z:2b1c 0.8 0.08 0.1 0.02 14 | OMIM:101 Y:1a1 0.8 0.08 0.1 0.02 15 | OMIM:102 Y:1a1 0.8 0.08 0.1 0.02 16 | OMIM:103 Y:1a1 0.8 0.08 0.1 0.02 17 | OMIM:104 Y:1a1 0.8 0.08 0.1 0.02 18 | OMIM:105 Y:1a1 0.8 0.08 0.1 0.02 19 | OMIM:106 Y:1a1 0.8 0.08 0.1 0.02 20 | OMIM:107 Y:1a1 0.8 0.08 0.1 0.02 21 | OMIM:108 Y:1a1 0.8 0.08 0.1 0.02 22 | OMIM:109 Y:1a1 0.8 0.08 0.1 0.02 23 | OMIM:110 Y:1a1 0.8 0.08 0.1 0.02 24 | OMIM:110 Y:1a1 0.8 0.2 0.0 0.0 25 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-nosol.tsv: -------------------------------------------------------------------------------- 1 | X:1 Y:1 0.02 0.02 0.95 0.01 2 | X:1 Z:1 0.01 0.01 0.99 0.01 3 | Y:1 Z:1 0.02 0.02 0.95 0.01 4 | X:2 Y:2 0.02 0.02 0.95 0.01 5 | X:2 Z:2 0.01 0.01 0.99 0.01 6 | Y:2 Z:2 0.02 0.02 0.95 0.01 7 | X:2 Y:1 0.03 0.02 0.94 0.01 8 | X:1 Z:2 0.03 0.02 0.94 0.01 9 | X:3 Y:3 0.02 0.02 0.95 0.01 10 | X:3 Z:3 0.01 0.01 0.99 0.01 11 | Y:3 Z:3 0.02 0.02 0.95 0.01 12 | X:3 Y:2 0.03 0.02 0.94 0.01 13 | X:2 Z:3 0.03 0.02 0.94 0.01 14 | X:4 Y:4 0.02 0.02 0.95 0.01 15 | X:4 Z:4 0.01 0.01 0.99 0.01 16 | Y:4 Z:4 0.02 0.02 0.95 0.01 17 | X:4 Y:3 0.03 0.02 0.94 0.01 18 | X:3 Z:4 0.03 0.02 0.94 0.01 19 | X:5 Y:5 0.02 0.02 0.95 0.01 20 | X:5 Z:5 0.01 0.01 0.99 0.01 21 | Y:5 Z:5 0.02 0.02 0.95 0.01 22 | X:5 Y:4 0.03 0.02 0.94 0.01 23 | X:4 Z:5 0.03 0.02 0.94 0.01 24 | X:6 Y:6 0.02 0.02 0.95 0.01 25 | X:6 Z:6 0.01 0.01 0.99 0.01 26 | Y:6 Z:6 0.02 0.02 0.95 0.01 27 | X:6 Y:5 0.03 0.02 0.94 0.01 28 | X:5 Z:6 0.03 0.02 0.94 0.01 29 | X:7 Y:7 0.02 0.02 0.95 0.01 30 | X:7 Z:7 0.01 0.01 0.99 0.01 31 | Y:7 Z:7 0.02 0.02 0.95 0.01 32 | X:7 Y:6 0.03 0.02 0.94 0.01 33 | X:6 Z:7 0.03 0.02 0.94 0.01 34 | X:8 Y:8 0.02 0.02 0.95 0.01 35 | X:8 Z:8 0.01 0.01 0.99 0.01 36 | Y:8 Z:8 0.02 0.02 0.95 0.01 37 | X:8 Y:7 0.03 0.02 0.94 0.01 38 | X:7 Z:8 0.03 0.02 0.94 0.01 39 | X:9 Y:9 0.02 0.02 0.95 0.01 40 | X:9 Z:9 0.01 0.01 0.99 0.01 41 | Y:9 Z:9 0.02 0.02 0.95 0.01 42 | X:9 Y:8 0.03 0.02 0.94 0.01 43 | X:8 Z:9 0.03 0.02 0.94 0.01 44 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-one-solution.tsv: -------------------------------------------------------------------------------- 1 | X:2b X:root 0.0 0.45 0.45 0.1 2 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-override.tsv: -------------------------------------------------------------------------------- 1 | X:2b X:root 0.01 0.49 0.2 0.3 2 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-reciprocal-conflict.tsv: -------------------------------------------------------------------------------- 1 | X:1 Y:1 0.9 0.05 0.05 0.0 2 | Y:1 X:1 0.85 0.05 0.0 0.1 3 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-trivial-4-combos.tsv: -------------------------------------------------------------------------------- 1 | A:1 B:1 0.7 0.1 0.1 0.1 2 | A:2 B:2 0.1 0.7 0.1 0.1 3 | A:3 B:3 0.1 0.1 0.7 0.1 4 | A:4 B:4 0.1 0.1 0.1 0.7 5 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-unsat-clique-test.tsv: -------------------------------------------------------------------------------- 1 | X:1 Y:1 0.2 0.2 0.6 0.1 2 | X:2 Y:2 0.1 0.1 0.75 0.05 3 | Y:2 Z:2 0.1 0.1 0.75 0.05 4 | Y:2 Z:2a 0.1 0.25 0.6 0.05 5 | Z:2a X:2 0.3 0.1 0.5 0.1 6 | Z:2b1a Y:2b1 0.2 0.2 0.5 0.1 7 | Z:2b1b Y:2b1 0.2 0.2 0.5 0.1 8 | Z:2b1c Y:2b1 0.19 0.2 0.51 0.1 9 | X:3 Z:3 0.1 0.1 0.75 0.05 10 | OMIM:001 Z:3 0.8 0.08 0.1 0.02 11 | OMIM:002 Z:3 0.8 0.08 0.1 0.02 12 | OMIM:003 Z:3 0.8 0.08 0.1 0.02 13 | OMIM:004 Z:3 0.8 0.08 0.1 0.02 14 | OMIM:005 Z:3 0.8 0.08 0.1 0.02 15 | OMIM:006 Z:3 0.8 0.08 0.1 0.02 16 | OMIM:007 Z:3 0.8 0.08 0.1 0.02 17 | OMIM:008 Z:3 0.8 0.08 0.1 0.02 18 | OMIM:009 Z:3 0.8 0.08 0.1 0.02 19 | OMIM:010 Z:3 0.8 0.08 0.1 0.02 20 | OMIM:010 X:3 0.025 0.025 0.9 0.05 21 | OMIM:010 X:2 0.025 0.025 0.85 0.1 22 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-unsat-clique-test2.tsv: -------------------------------------------------------------------------------- 1 | X:1 Y:1 0.2 0.2 0.6 0.1 2 | X:2 Y:2 0.1 0.1 0.75 0.05 3 | Y:2 Z:2 0.1 0.1 0.75 0.05 4 | Y:2 Z:2a 0.1 0.25 0.6 0.05 5 | Z:2a X:2 0.3 0.1 0.5 0.1 6 | Z:2b1a Y:2b1 0.2 0.2 0.5 0.1 7 | Z:2b1b Y:2b1 0.2 0.2 0.5 0.1 8 | Z:2b1c Y:2b1 0.19 0.2 0.51 0.1 9 | X:3 Z:3 0.1 0.1 0.75 0.05 10 | OMIM:001 Z:3 0.8 0.08 0.1 0.02 11 | OMIM:002 Z:3 0.8 0.08 0.1 0.02 12 | OMIM:003 Z:3 0.8 0.08 0.1 0.02 13 | OMIM:004 Z:3 0.8 0.08 0.1 0.02 14 | OMIM:005 Z:3 0.8 0.08 0.1 0.02 15 | OMIM:006 Z:3 0.8 0.08 0.1 0.02 16 | OMIM:007 Z:3 0.8 0.08 0.1 0.02 17 | OMIM:008 Z:3 0.8 0.08 0.1 0.02 18 | OMIM:009 Z:3 0.8 0.08 0.1 0.02 19 | OMIM:010 Z:3 0.8 0.08 0.1 0.02 20 | OMIM:010 X:3 0.025 0.025 0.9 0.05 21 | OMIM:010 X:2 0.125 0.025 0.85 0.0 22 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/ptable-unsatisfiable.tsv: -------------------------------------------------------------------------------- 1 | X:2b X:root 0.0 0.5 0.5 0.0 2 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/trivial-4-combos.obo: -------------------------------------------------------------------------------- 1 | ontology: trivil 2 | remark: fake ontology 3 | 4 | [Term] 5 | id: A:1 6 | name: a1 7 | 8 | [Term] 9 | id: B:1 10 | name: b1 11 | 12 | [Term] 13 | id: A:2 14 | name: a2 15 | 16 | [Term] 17 | id: B:2 18 | name: b2 19 | 20 | [Term] 21 | id: A:3 22 | name: a3 23 | 24 | [Term] 25 | id: B:3 26 | name: b3 27 | 28 | [Term] 29 | id: A:4 30 | name: a4 31 | 32 | [Term] 33 | id: B:4 34 | name: b4 35 | 36 | -------------------------------------------------------------------------------- /boom-core/src/test/resources/x-ontology-subclass.obo: -------------------------------------------------------------------------------- 1 | ontology: x 2 | 3 | [Term] 4 | id: Z:1 5 | name: z1 6 | 7 | [Term] 8 | id: X:1 9 | name: x1 10 | 11 | [Term] 12 | id: Y:1 13 | is_a: X:1 14 | name: "y1" 15 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | org.monarchinitiative.boom 5 | boom 6 | 1.0-SNAPSHOT 7 | boom 8 | pom 9 | 10 | 11 | boom-core 12 | 13 | 14 | 15 | UTF-8 16 | UTF-8 17 | 4.2.3 18 | 0.7.1 19 | 4.0 20 | 21 | 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-compiler-plugin 26 | 2.5.1 27 | 28 | 1.8 29 | 1.8 30 | 31 | 32 | 33 | org.apache.maven.plugins 34 | maven-surefire-plugin 35 | 2.12.2 36 | 37 | -Xmx2200M 38 | 39 | 40 | 41 | org.apache.maven.plugins 42 | maven-eclipse-plugin 43 | 2.9 44 | 45 | true 46 | true 47 | 48 | 49 | 50 | org.apache.maven.plugins 51 | maven-failsafe-plugin 52 | 2.17 53 | 54 | 55 | 56 | integration-test 57 | verify 58 | 59 | 60 | 61 | 62 | 63 | org.eluder.coveralls 64 | coveralls-maven-plugin 65 | 3.0.1 66 | 67 | 9xzW6udEMsX8PzQR9efXb1TwksQmltfNI 68 | 69 | 70 | 71 | org.codehaus.mojo 72 | cobertura-maven-plugin 73 | 2.6 74 | 75 | xml 76 | 256m 77 | 78 | true 79 | 80 | 81 | 82 | 83 | 84 | 85 | junit 86 | junit 87 | 4.12 88 | test 89 | 90 | 91 | com.google.caliper 92 | caliper 93 | 1.0-beta-1 94 | 95 | 96 | com.google.inject 97 | guice 98 | ${guice.version} 99 | 100 | 101 | com.google.guava 102 | guava 103 | 18.0 104 | 105 | 106 | org.mockito 107 | mockito-all 108 | 1.10.8 109 | test 110 | 111 | 112 | org.hamcrest 113 | hamcrest-library 114 | 1.3 115 | test 116 | 117 | 118 | com.carrotsearch 119 | junit-benchmarks 120 | 0.7.2 121 | test 122 | 123 | 124 | com.google.code.findbugs 125 | jsr305 126 | 3.0.0 127 | compile 128 | 129 | 130 | 131 | 132 | --------------------------------------------------------------------------------