/* * * YAQP - Yet Another QSAR Project: * Machine Learning algorithms designed for the prediction of toxicological * features of chemical compounds become available on the Web. Yaqp is developed * under OpenTox (http://opentox.org) which is an FP7-funded EU research project. * This project was developed at the Automatic Control Lab in the Chemical Engineering * School of the National Technical University of Athens. Please read README for more * information. * * Copyright (C) 2009-2010 Pantelis Sopasakis & Charalampos Chomenides * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Contact: * Pantelis Sopasakis * chvng@mail.ntua.gr * Address: Iroon Politechniou St. 9, Zografou, Athens Greece * tel. +30 210 7723236 */ package org.opentox.ontology.components; import com.hp.hpl.jena.datatypes.xsd.XSDDatatype; import com.hp.hpl.jena.ontology.Individual; import com.hp.hpl.jena.vocabulary.DC; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.opentox.core.exceptions.Cause; import org.opentox.core.exceptions.YaqpException; import org.opentox.io.exceptions.YaqpIOException; import org.opentox.io.publishable.JSONObject; import org.opentox.io.publishable.PDFObject; import org.opentox.io.publishable.RDFObject; import org.opentox.io.publishable.UriListObject; import org.opentox.io.util.YaqpIOStream; import org.opentox.ontology.namespaces.OTClass; import org.opentox.ontology.namespaces.OTDataTypeProperties; import org.opentox.ontology.namespaces.OTObjectProperties; import org.opentox.ontology.util.AlgorithmParameter; import org.opentox.ontology.util.Meta; import org.opentox.ontology.util.YaqpAlgorithms; import org.opentox.ontology.util.vocabulary.ConstantParameters; /** * * @author Pantelis Sopasakis * @author Charalampos Chomenides */ public class QSARModel extends YaqpComponent { //private ArrayList<AlgorithmParameter> tuningParams = new ArrayList<AlgorithmParameter>(); private Map<String, AlgorithmParameter> params = new HashMap<String, AlgorithmParameter>(); private int id = 0; private int _minId = Integer.MIN_VALUE, _maxId = Integer.MAX_VALUE; private String code = null; private Feature predictionFeature = new Feature(); private Feature dependentFeature = new Feature(); private ArrayList<Feature> independentFeatures = new ArrayList<Feature>(); private Algorithm algorithm = new Algorithm(); private User user = new User(); private String timestamp = null; private String dataset = null; private ModelStatus modelStatus = null; private boolean hasVec = false; private final double doubleMax = (double)Integer.MAX_VALUE; public enum ModelStatus { APPROVED { @Override public String toString() { return "APPROVED"; } ; }, UNDER_DEVELOPMENT { @Override public String toString() { return "UNDER_DEVELOPMENT"; } ; } } public QSARModel() { super(); } private QSARModel(int id) { this.id = id; } public QSARModel( String code, Feature predictionFeature, Feature dependentFeature, ArrayList<Feature> independentFeatures, Algorithm algorithm, User user, String timestamp, String dataset, ModelStatus modelStatus) { this(); this.code = code; this.predictionFeature = predictionFeature; this.dependentFeature = dependentFeature; this.independentFeatures = independentFeatures; this.algorithm = algorithm; this.user = user; this.timestamp = timestamp; this.dataset = dataset; if( modelStatus != null){ this.modelStatus = modelStatus; }else{ this.modelStatus = ModelStatus.UNDER_DEVELOPMENT; } } public QSARModel( int id, String code, Feature predictionFeature, Feature dependentFeature, ArrayList<Feature> independentFeatures, Algorithm algorithm, User user, String timestamp, String dataset, ModelStatus modelStatus, Map<String, AlgorithmParameter> tuningParams) { this(code, predictionFeature, dependentFeature, independentFeatures, algorithm, user, timestamp, dataset, modelStatus); this.id = id; this._maxId = id; this._minId = id; this.params = checkParams(tuningParams); } public int getMaxId() { return _maxId; } public void setMaxId(int _maxId) { this._maxId = _maxId; } public int getMinId() { return _minId; } public void setMinId(int _minId) { this._minId = _minId; } public Algorithm getAlgorithm() { return algorithm; } public void setAlgorithm(Algorithm algorithm) { this.algorithm = algorithm; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getDataset() { return dataset; } public void setDataset(String dataset) { this.dataset = dataset; } public Feature getDependentFeature() { return dependentFeature; } public void setDependentFeature(Feature dependentFeature) { this.dependentFeature = dependentFeature; } public int getId() { return id; } public void setId(int id) { this.id = id; this._maxId = id; this._minId = id; } public ArrayList<Feature> getIndependentFeatures() { return independentFeatures; } public void setIndependentFeatures(ArrayList<Feature> independentFeatures) { this.independentFeatures = independentFeatures; } public ModelStatus getModelStatus() { return modelStatus; } public void setModelStatus(ModelStatus modelStatus) { this.modelStatus = modelStatus; } public Feature getPredictionFeature() { return predictionFeature; } public void setPredictionFeature(Feature predictionFeature) { this.predictionFeature = predictionFeature; } public String getTimestamp() { return timestamp; } public void setTimestamp(String timestamp) { this.timestamp = timestamp; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Map<String, AlgorithmParameter> getParams() { return params; } public void setParams(Map<String, AlgorithmParameter> params) { this.params = checkParams(params); } public boolean hasVec(){ return hasVec; } // public ArrayList<AlgorithmParameter> getTuningParams() { // return tuningParams; // } // // public void setTuningParams(ArrayList<AlgorithmParameter> tuningParams) { // this.tuningParams = tuningParams; // } // TODO: Implement this method ASAP (due for Feb 17)! @Override public PDFObject getPDF() { PDFObject pdf = new PDFObject(); return pdf; } // TODO: Implement this method ASAP (due for Feb 17)! /** * As fas as the model parameters are concerned, a set of individuals will be created * for the data model each one of which corresponds to an entry of the parameters map * which is available through {@link QSARModel#getParams() }. You have to specify * correctly these parameters in order to avoid issued with the RDF representation of * the QSARModel. * @return */ @Override public RDFObject getRDF() { RDFObject rdf = new RDFObject(); // SOME ONTOLOGICAL CLASES ARE CONTAINED IN THE DATASET rdf.includeOntClasses(OTClass.Dataset, OTClass.Algorithm, OTClass.Feature, OTClass.Model, OTClass.User, OTClass.UserGroup, OTClass.Parameter); // THE WHOLE REPRESENTATION OF THE ALGORITHM IS INCLUDED IN THE DATA MODEL // OF THE QSAR MODEL. rdf = new RDFObject( rdf.union(getAlgorithm().getRDF()) ); try { Individual qsarModel = rdf.createIndividual(uri().toString(), rdf.createOntResource(OTClass.Model.getURI())); Individual algIndiv = rdf.createIndividual(getAlgorithm().uri().toString(), rdf.createOntResource(OTClass.Algorithm.getURI())); qsarModel.addProperty(OTObjectProperties.algorithm.createProperty(rdf), algIndiv); // STANDARD META INFORMATION ABOUT THE MODEL LIKE THE PHBLISHER, THE AUDIENCE AND SO ON // SOME OF THESE ARE THE GLOBAL META DATA FOR ALL YAQP ENTITIES (LIKE THE PUBLISHER). FOR OTHER, LIKE // THE AUDIENCES, META INFO ARE ADAPTED FROM THOSE OF THE TRAINING ALGORITHM. Meta standardeModelMeta = new Meta(); /* title */ qsarModel.addLiteral( rdf.createAnnotationProperty(DC.title.getURI()), rdf.createTypedLiteral( "Predictive QSAR Model generated by the algorithm " + getAlgorithm().getMeta().getName(), XSDDatatype.XSDstring)); /* description */ qsarModel.addLiteral( rdf.createAnnotationProperty(DC.description.getURI()), rdf.createTypedLiteral( "Predictive QSAR Model generated by the algorithm " + getAlgorithm().getMeta().getName() + " for the prediction of the feature " + getDependentFeature().getURI(), XSDDatatype.XSDstring)); /* identifier */ qsarModel.addLiteral(rdf.createAnnotationProperty(DC.identifier.getURI()), rdf.createTypedLiteral(uri().toString(), XSDDatatype.XSDanyURI)); /* publisher */ qsarModel.addLiteral(rdf.createAnnotationProperty(DC.publisher.getURI()), rdf.createTypedLiteral(standardeModelMeta.publisher, XSDDatatype.XSDstring)); /* */ qsarModel.addLiteral(rdf.createAnnotationProperty(DC.date.getURI()), rdf.createTypedLiteral(standardeModelMeta.date, XSDDatatype.XSDdate)); /* language */ qsarModel.addLiteral(rdf.createAnnotationProperty(DC.language.getURI()), rdf.createTypedLiteral(standardeModelMeta.language, XSDDatatype.XSDstring)); /* rights */ qsarModel.addLiteral(rdf.createAnnotationProperty(DC.rights.getURI()), rdf.createTypedLiteral(standardeModelMeta.rights, XSDDatatype.XSDstring)); /* training dataset */ Individual datasetIndiv = rdf.createIndividual(getDataset(), rdf.createOntResource(OTClass.Dataset.getURI())); datasetIndiv.addComment("The dataset used to train the model", Locale.ENGLISH.getLanguage()); qsarModel.addProperty(rdf.createAnnotationProperty(OTObjectProperties.trainingDataset.getURI()), datasetIndiv); /* */ // Add all parameters: Individual iparam; Map<String, AlgorithmParameter> paraMap = getParams(); final Set<Entry<String, AlgorithmParameter>> entrySet = paraMap.entrySet(); for (Entry<String, AlgorithmParameter> e : entrySet){ iparam = rdf.createIndividual(OTClass.Parameter.getOntClass(rdf)); iparam.addProperty(rdf.createAnnotationProperty(DC.title.getURI()), e.getKey()); iparam.addLiteral(OTDataTypeProperties.paramValue.createProperty(rdf), e.getValue().paramValue.toString()); qsarModel.addProperty(OTObjectProperties.parameters.createProperty(rdf), iparam); } /* * Add the dependent feature */ qsarModel.addProperty(OTObjectProperties.dependentVariables.createProperty(rdf), rdf.createOntResource(getDependentFeature().getURI())); qsarModel.addProperty(OTObjectProperties.predictedVariables.createProperty(rdf), rdf.createOntResource(getPredictionFeature().getURI())); /** * Add the independent features */ final ArrayList<Feature > indFeats = getIndependentFeatures(); for (Feature indF : indFeats){ qsarModel.addProperty(OTObjectProperties.independentVariables.createProperty(rdf), rdf.createOntResource(indF.getURI())); } } catch (YaqpException ex) { /* What should be done? */ } return rdf; } public static void main(String... args) throws YaqpIOException{ QSARModel m = new QSARModel("sdfsdfsdf", new Feature(), new Feature(), new ArrayList<Feature>(), YaqpAlgorithms.MLR, new User(), "", null, ModelStatus.APPROVED); m.setParams(new HashMap<String, AlgorithmParameter>()); m.setDataset("http://someserver.com/dataset/10"); m.getRDF().publish(new YaqpIOStream(System.out)); } @Override public JSONObject getJson() { throw new UnsupportedOperationException("Not supported yet."); } @Override protected String getTag() { return "model"; } @Override public URI uri() throws YaqpException { String superUri = super.uri().toString(); try { return new URI(superUri + "/" + getId()); } catch (URISyntaxException ex) { throw new YaqpException(Cause.XTC743, "Improper URI", ex); } } @SuppressWarnings({"unchecked"}) private Map<String, AlgorithmParameter> initParams() { Map<String,AlgorithmParameter> newParams = new HashMap<String,AlgorithmParameter>(); newParams.put(ConstantParameters.gamma+"_min", new AlgorithmParameter(0.0)); newParams.put(ConstantParameters.gamma+"_max", new AlgorithmParameter(doubleMax)); newParams.put(ConstantParameters.epsilon+"_min", new AlgorithmParameter(0.0)); newParams.put(ConstantParameters.epsilon+"_max", new AlgorithmParameter(doubleMax)); newParams.put(ConstantParameters.cost+"_min", new AlgorithmParameter(0.0)); newParams.put(ConstantParameters.cost+"_max", new AlgorithmParameter(doubleMax)); newParams.put(ConstantParameters.coeff0+"_min", new AlgorithmParameter(0.0)); newParams.put(ConstantParameters.coeff0+"_max", new AlgorithmParameter(doubleMax)); newParams.put(ConstantParameters.tolerance+"_min", new AlgorithmParameter(0.0)); newParams.put(ConstantParameters.tolerance+"_max", new AlgorithmParameter(doubleMax)); newParams.put(ConstantParameters.cacheSize+"_min", new AlgorithmParameter(0)); newParams.put(ConstantParameters.cacheSize+"_max", new AlgorithmParameter(Integer.MAX_VALUE)); newParams.put(ConstantParameters.kernel, new AlgorithmParameter("%%")); newParams.put(ConstantParameters.degree+"_min", new AlgorithmParameter(0)); newParams.put(ConstantParameters.degree+"_max", new AlgorithmParameter(Integer.MAX_VALUE)); return newParams; } private Map<String,AlgorithmParameter> checkParams(Map<String,AlgorithmParameter> params){ Map<String,AlgorithmParameter> newParams = initParams(); if ((params.get(ConstantParameters.gamma) != null && params.get(ConstantParameters.gamma).paramValue != null)){ newParams.put(ConstantParameters.gamma, params.get(ConstantParameters.gamma)); newParams.put(ConstantParameters.gamma+"_min", params.get(ConstantParameters.gamma)); newParams.put(ConstantParameters.gamma+"_max", params.get(ConstantParameters.gamma)); hasVec = true; }else{ if ((params.get(ConstantParameters.gamma+"_min") != null && params.get(ConstantParameters.gamma+"_min").paramValue != null)){ newParams.put(ConstantParameters.gamma+"_min", params.get(ConstantParameters.gamma+"_min")); hasVec = true; } if ((params.get(ConstantParameters.gamma+"_max") != null && params.get(ConstantParameters.gamma+"_max").paramValue != null)){ newParams.put(ConstantParameters.gamma+"_max", params.get(ConstantParameters.gamma+"_max")); hasVec = true; } } if ((params.get(ConstantParameters.epsilon) != null && params.get(ConstantParameters.epsilon).paramValue != null)){ newParams.put(ConstantParameters.epsilon, params.get(ConstantParameters.epsilon)); newParams.put(ConstantParameters.epsilon+"_min", params.get(ConstantParameters.epsilon)); newParams.put(ConstantParameters.epsilon+"_max", params.get(ConstantParameters.epsilon)); hasVec = true; }else{ if ((params.get(ConstantParameters.epsilon+"_min") != null && params.get(ConstantParameters.epsilon+"_min").paramValue != null)){ newParams.put(ConstantParameters.epsilon+"_min", params.get(ConstantParameters.epsilon+"_min")); hasVec = true; } if ((params.get(ConstantParameters.epsilon+"_max") != null && params.get(ConstantParameters.epsilon+"_max").paramValue != null)){ newParams.put(ConstantParameters.epsilon+"_max", params.get(ConstantParameters.epsilon+"_max")); hasVec = true; } } if ((params.get(ConstantParameters.cost) != null && params.get(ConstantParameters.cost).paramValue != null)){ newParams.put(ConstantParameters.cost, params.get(ConstantParameters.cost)); newParams.put(ConstantParameters.cost+"_min", params.get(ConstantParameters.cost)); newParams.put(ConstantParameters.cost+"_max", params.get(ConstantParameters.cost)); hasVec = true; }else{ if ((params.get(ConstantParameters.cost+"_min") != null && params.get(ConstantParameters.cost+"_min").paramValue != null)){ newParams.put(ConstantParameters.cost+"_min", params.get(ConstantParameters.cost+"_min")); hasVec = true; } if ((params.get(ConstantParameters.cost+"_max") != null && params.get(ConstantParameters.cost+"_max").paramValue != null)){ newParams.put(ConstantParameters.cost+"_max", params.get(ConstantParameters.cost+"_max")); hasVec = true; } } if ((params.get(ConstantParameters.coeff0) != null && params.get(ConstantParameters.coeff0).paramValue != null)){ newParams.put(ConstantParameters.coeff0, params.get(ConstantParameters.coeff0)); newParams.put(ConstantParameters.coeff0+"_min", params.get(ConstantParameters.coeff0)); newParams.put(ConstantParameters.coeff0+"_max", params.get(ConstantParameters.coeff0)); hasVec = true; }else{ if ((params.get(ConstantParameters.coeff0+"_min") != null && params.get(ConstantParameters.coeff0+"_min").paramValue != null)){ newParams.put(ConstantParameters.coeff0+"_min", params.get(ConstantParameters.coeff0+"_min")); hasVec = true; } if ((params.get(ConstantParameters.coeff0+"_max") != null && params.get(ConstantParameters.coeff0+"_max").paramValue != null)){ newParams.put(ConstantParameters.coeff0+"_max", params.get(ConstantParameters.coeff0+"_max")); hasVec = true; } } if ((params.get(ConstantParameters.cacheSize) != null && params.get(ConstantParameters.cacheSize).paramValue != null)){ newParams.put(ConstantParameters.cacheSize, params.get(ConstantParameters.cacheSize)); newParams.put(ConstantParameters.cacheSize+"_min", params.get(ConstantParameters.cacheSize)); newParams.put(ConstantParameters.cacheSize+"_max", params.get(ConstantParameters.cacheSize)); hasVec = true; }else{ if ((params.get(ConstantParameters.cacheSize+"_min") != null && params.get(ConstantParameters.cacheSize+"_min").paramValue != null)){ newParams.put(ConstantParameters.cacheSize+"_min", params.get(ConstantParameters.cacheSize+"_min")); hasVec = true; } if ((params.get(ConstantParameters.cacheSize+"_max") != null && params.get(ConstantParameters.cacheSize+"_max").paramValue != null)){ newParams.put(ConstantParameters.cacheSize+"_max", params.get(ConstantParameters.cacheSize+"_max")); hasVec = true; } } if ((params.get(ConstantParameters.tolerance) != null && params.get(ConstantParameters.tolerance).paramValue != null)){ newParams.put(ConstantParameters.tolerance, params.get(ConstantParameters.tolerance)); newParams.put(ConstantParameters.tolerance+"_min", params.get(ConstantParameters.tolerance)); newParams.put(ConstantParameters.tolerance+"_max", params.get(ConstantParameters.tolerance)); hasVec = true; }else{ if ((params.get(ConstantParameters.tolerance+"_min") != null && params.get(ConstantParameters.tolerance+"_min").paramValue != null)){ newParams.put(ConstantParameters.tolerance+"_min", params.get(ConstantParameters.tolerance+"_min")); hasVec = true; } if ((params.get(ConstantParameters.tolerance+"_max") != null && params.get(ConstantParameters.tolerance+"_max").paramValue != null)){ newParams.put(ConstantParameters.tolerance+"_max", params.get(ConstantParameters.tolerance+"_max")); hasVec = true; } } if ((params.get(ConstantParameters.degree) != null && params.get(ConstantParameters.degree).paramValue != null)){ newParams.put(ConstantParameters.degree, params.get(ConstantParameters.degree)); newParams.put(ConstantParameters.degree+"_min", params.get(ConstantParameters.degree)); newParams.put(ConstantParameters.degree+"_max", params.get(ConstantParameters.degree)); hasVec = true; }else{ if ((params.get(ConstantParameters.degree+"_min") != null && params.get(ConstantParameters.degree+"_min").paramValue != null)){ newParams.put(ConstantParameters.degree+"_min", params.get(ConstantParameters.degree+"_min")); hasVec = true; } if ((params.get(ConstantParameters.degree+"_max") != null && params.get(ConstantParameters.degree+"_max").paramValue != null)){ newParams.put(ConstantParameters.degree+"_max", params.get(ConstantParameters.degree+"_max")); hasVec = true; } } if ((params.get(ConstantParameters.kernel) != null && params.get(ConstantParameters.kernel).paramValue != null)){ newParams.put(ConstantParameters.kernel, params.get(ConstantParameters.kernel)); hasVec = true; } return newParams; } @Override public UriListObject getUriList() { ArrayList<URI> uriList = new ArrayList<URI>(1); try { uriList.add(uri()); return new UriListObject(uriList); } catch (YaqpException ex) { return null; } } @Override public QSARModel getSkroutz(){ return new QSARModel(this.getId()); } @Override public boolean equals(Object obj){ if(obj.getClass() == this.getClass()){ QSARModel model = (QSARModel) obj; return (this.getId() == model.getId()); }else{ return false; } } @Override public int hashCode() { int hash = 3; hash = 59 * hash + this.id; return hash; } }