/**
*
*/
package se.liu.imt.mi.snomedct.expression.tools;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.semanticweb.elk.owlapi.ElkReasonerFactory;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.formats.FunctionalSyntaxDocumentFormat;
import org.semanticweb.owlapi.formats.TurtleDocumentFormat;
import org.semanticweb.owlapi.model.AddAxiom;
import org.semanticweb.owlapi.model.AddImport;
import org.semanticweb.owlapi.model.AxiomType;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLClassExpression;
import org.semanticweb.owlapi.model.OWLDocumentFormat;
import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom;
import org.semanticweb.owlapi.model.OWLException;
import org.semanticweb.owlapi.model.OWLImportsDeclaration;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyChange;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLSubClassOfAxiom;
import org.semanticweb.owlapi.normalform.NormalFormRewriter;
import org.semanticweb.owlapi.reasoner.InferenceType;
import org.semanticweb.owlapi.reasoner.OWLReasoner;
import org.semanticweb.owlapi.reasoner.OWLReasonerFactory;
import se.liu.imt.mi.snomedct.parser.SNOMEDCTDocumentFormat;
import se.liu.imt.mi.snomedct.parser.SNOMEDCTOntologyStorerFactory;
import se.liu.imt.mi.snomedct.parser.SNOMEDCTParserFactory;
/**
* @author Daniel Karlsson, Linköping Univsrsity, daniel.karlsson@liu.se
* @author Kent Spackman, IHTSDO, ksp@ihtsdo.org
*
*
*/
public class SNOMEDCTTranslator {
static Logger logger = Logger.getLogger(SNOMEDCTTranslator.class);
/**
* @param args
* @throws OWLException
*/
public static void main(String[] args) throws OWLException {
// create Options object
Options options = new Options();
// add OWL output format option
options.addOption("f", "owl-format", true,
"OWL output format [turtle|owlf|sct]");
// add normal form/stated option
options.addOption("n", "normal-form", true,
"output normal form [stated|distribution|flat]");
// add SNOMED CT ontology file option
options.addOption("s", "snomed-file", true, "SNOMED CT ontology file");
// add labels option
options.addOption("l", "labels", false, "show labels in output");
CommandLineParser parser = new DefaultParser();
CommandLine cmd = null;
try {
cmd = parser.parse(options, args);
} catch (ParseException e) {
e.printStackTrace();
System.exit(1);
}
String format = cmd.getOptionValue("owl-format", "sct");
String normalForm = cmd.getOptionValue("normal-form", "stated");
String snomedCTFile = cmd.getOptionValue("snomed-file");
boolean labels = cmd.hasOption("labels");
List<?> argList = (List<?>) cmd.getArgList();
if (argList.size() < 1) {
HelpFormatter f = new HelpFormatter();
f.printHelp("SNOMEDCTTranslator", options);
System.exit(2);
}
// get input file name from argument list
String inputFileName = (String) argList.get(0);
// get output file name from argument list or create a new output file
// name from the input file name
String outputFileName;
if (argList.size() < 2) {
// separate out the extension (after last '.')
String[] tokens = inputFileName.split("\\.(?=[^\\.]+$)");
if (tokens.length >= 2)
outputFileName = tokens[0] + "_" + format + "_" + normalForm
+ "." + tokens[1];
else
outputFileName = inputFileName + "_" + format + "_"
+ normalForm;
} else
outputFileName = (String) argList.get(1);
OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
// add SNOMED CT parser and storer to manager
manager.getOntologyParsers().add(new SNOMEDCTParserFactory());
manager.getOntologyStorers().add(new SNOMEDCTOntologyStorerFactory());
OWLOntology ontology = manager
.loadOntologyFromOntologyDocument(new File(inputFileName));
OWLDocumentFormat ontologyFormat = null;
switch (format) {
case "turtle":
ontologyFormat = new TurtleDocumentFormat();
break;
case "owlf":
ontologyFormat = new FunctionalSyntaxDocumentFormat();
break;
case "sct": // SNOMED CT Compositional Grammar
ontologyFormat = new SNOMEDCTDocumentFormat();
ontologyFormat.setParameter("labels", labels);
break;
default:
System.exit(1);
}
if (normalForm.equals("stated")) {
// if stated form, just output the ontology in the selected format
manager.saveOntology(ontology, ontologyFormat,
IRI.create(new File(outputFileName)));
} else if (normalForm.equals("distribution")
|| normalForm.equals("flat")) {
// if not stated form, classify the ontology, possibly after first
// importing (a module from) SNOMED CT
if (snomedCTFile != null) {
// Import SNOMED CT ontology
IRI snomedCTIRI = IRI.create(new File(snomedCTFile));
OWLImportsDeclaration importDeclaration = ontology
.getOWLOntologyManager().getOWLDataFactory()
.getOWLImportsDeclaration(snomedCTIRI);
ontology.getOWLOntologyManager().loadOntology(snomedCTIRI);
ontology.getOWLOntologyManager().applyChange(
new AddImport(ontology, importDeclaration));
}
NormalFormRewriter normalFormConverter = null;
// create a fresh empty ontology for output of inferred expression
OWLOntologyManager outputManager = OWLManager
.createOWLOntologyManager();
// add SNOMED CT storer to ontology manager
outputManager.getOntologyStorers().add(new SNOMEDCTOntologyStorerFactory());
OWLOntology inferredOntology = outputManager.createOntology();
List<OWLOntologyChange> changes = new ArrayList<OWLOntologyChange>();
if (normalForm.equals("distribution")) {
// Create reasoner and classify the ontology including SNOMED CT
OWLReasonerFactory reasonerFactory = new ElkReasonerFactory();
OWLReasoner reasoner = reasonerFactory.createReasoner(ontology);
Logger.getLogger("org.semanticweb.elk").setLevel(Level.ERROR);
reasoner.flush();
reasoner.precomputeInferences(InferenceType.CLASS_HIERARCHY);
// create the normal form converter
normalFormConverter = new DistributionNormalFormConverter(
ontology, reasoner);
// // add annotations from original ontology
// for (OWLOntology o : reasoner.getRootOntology()
// .getImportsClosure()) {
// for (OWLAnnotation annot : o.getAnnotations()) {
// changes.add(new AddOntologyAnnotation(inferredOntology,
// annot));
// }
// for (OWLAnnotationAssertionAxiom axiom : o
// .getAxioms(AxiomType.ANNOTATION_ASSERTION)) {
// changes.add(new AddAxiom(inferredOntology, axiom));
// }
// }
} else
normalFormConverter = new Flattener(manager);
// iterate over equivalent classes axioms in the source ontology
for (OWLEquivalentClassesAxiom eqAxiom : ontology
.getAxioms(AxiomType.EQUIVALENT_CLASSES)) {
// logger.info("axiom = " + eqAxiom.toString());
// the equivalent classes axiom is assumed to have only two
// class expressions, the second (right hand side) being the
// class definition. As the source ontology is resulting from a
// set of Compositional Grammar expressions, e.g. concept
// inclusion is not possible.
Iterator<OWLClassExpression> expressionSet = eqAxiom
.getClassExpressions().iterator();
OWLClassExpression lhs = expressionSet.next(); // left hand side
OWLClassExpression rhs = expressionSet.next(); // right hand
// side
// convert the class definition to normal form
OWLClassExpression normalFormExpression = normalFormConverter
.convertToNormalForm(rhs);
// logger.info("expression = " + rhs.toString());
// logger.info("normal form = " + normalFormExpression);
changes.add(new AddAxiom(inferredOntology,
inferredOntology
.getOWLOntologyManager()
.getOWLDataFactory()
.getOWLEquivalentClassesAxiom(lhs,
normalFormExpression)));
}
// iterate over subclass axioms in the source ontology
for (OWLSubClassOfAxiom subClassAxiom : ontology
.getAxioms(AxiomType.SUBCLASS_OF)) {
// logger.info("axiom = " + subClassAxiom.toString());
OWLClassExpression lhs = subClassAxiom.getSubClass(); // left
// hand
// side
OWLClassExpression rhs = subClassAxiom.getSuperClass(); // right
// hand
// side
// convert the class definition to normal form
OWLClassExpression normalFormExpression = normalFormConverter
.convertToNormalForm(rhs);
// logger.info("expression = " + rhs.toString());
// logger.info("normal form = " + normalFormExpression);
changes.add(new AddAxiom(inferredOntology, inferredOntology
.getOWLOntologyManager().getOWLDataFactory()
.getOWLSubClassOfAxiom(lhs, normalFormExpression)));
}
outputManager.applyChanges(changes);
// save the ontology in the selected format
outputManager.saveOntology(inferredOntology, ontologyFormat,
IRI.create(new File(outputFileName)));
}
}
}