⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rmodel.java

📁 化学图形处理软件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package org.openscience.cdk.qsar.model.R2;import org.openscience.cdk.qsar.model.IModel;import org.openscience.cdk.qsar.model.QSARModelException;import org.openscience.cdk.tools.LoggingTool;import org.rosuda.JRI.REXP;import org.rosuda.JRI.RList;import org.rosuda.JRI.RMainLoopCallbacks;import org.rosuda.JRI.Rengine;import java.awt.*;import java.io.*;import java.util.HashMap;import java.util.Iterator;import java.util.Random;import java.util.Set;/** * Base class for the R-CDK interface. * <p/> * This class provides the basis for all classes that wish to interface with * R functions from a CDK program. * <p/> * Since the R engine is multi-threaded only one instance of the R session can exist * for a given Java process. This implies that initialization must be perfored exactly once * within a Java process. This class ensure that this occurs. * <p/> * In addition, this class loads some helper functions into the R session. The loading * can be via a temporary file (the default) or via a String, which may be useful in * webservice scenarios. * <p/> * <b>Requirement</b> The class (and implementing subclasses) is dependent on the * <a href="http://rosuda.org/JRI/">JRI</a> library. This provides an interface to R * for Java code. Though the <a href="http://rosuda.org/rJava/">rJava</a> for R * includes JRI, the code here is only dependent on JRI and does not attempt to * go from R to Java. Hence rJava is not a requirement. To compile this code, the CDK * includes the JRI jar file. However to run the code, the JRI native library (libjri.so * on Linux) must be located in the users LD_LIBRARY_PATH. Also the versions of the JRI Java * API and native library should match and this is checked for. * <p/> * Currently the CDK uses JRI 0.3 (available from <a href="  http://rosuda.org/R/nightly/other/JRI_0.3-0.tar.gz">here</a>) * <p/> * <p/> * <b>Implementation Notes</b> * <ul> * <li>If the user requires other initializations the only way to do so at * this point is to edit <code>helper.R</code> or perform the initialization by hand * <li>An implementing class must call <code>super()</code> * <li>Though this class provides a field to store the R model object as a * <code>RList</code> the actual R variable will remain in the R session. This is useful * for saving the model as a .Rda file at one point. Also by storing the model on the R * side we do not not need to make repeated queries on the model via <code>eval()</code>. * <li>Subclasses of this class are generally Java front-ends to a specific R model type * (such as linear regression, CNN etc.). Thus each subclass should provide getter methods * for the various components of such an object. Since this is tedious to do by hand, * you can use the <code>stubs.R</code> script that comes with the CDK distribution to * generate source code for the getter methods for the individual components of an R model * object. Note, that the script currently ignores objects of classes <code>'call'</code> * and <code>'formula'</code>. * </ul> * <p/> * <b>NOTE</b>: For the R backend to work, ensure that R is correctly installed. * Other requirements are * <ul> * <li>LD_LIBRARY_PATH should include the directory that contains <code>libjri.so</code>  as well * as the dierctory that contains <code>libR.so</code> * <li>R_HOME should be set to the appropriate location * </ul> * * @author      Rajarshi Guha * @cdk.require r-project * @cdk.require JRI.jar * @cdk.require java1.5+ * @cdk.module  qsar * @cdk.keyword R * @cdk.keyword JRI */public abstract class RModel implements IModel {    private String modelName = null;    protected RList modelObject = null;    protected HashMap params = null;    /**     * The object that performs the calls to the R engine.     */    protected static Rengine rengine = null;    /**     * A boolean that indicates whether the R/Java subsystem has been initialized or not.     */    private static boolean doneInit = false;    private static LoggingTool logger;    private void initRengine(String[] args, boolean useDisk) throws QSARModelException {        if (!doneInit) {            rengine = new Rengine(args, false, new TextConsole());            if (!rengine.waitForR()) {                throw new QSARModelException("Could not load rJava");            } else {                logger.debug("Started R");            }            doneInit = true;            if (useDisk) {                loadRFunctions(rengine);                logger.info("Initializing from disk");            } else {                loadRFunctionsAsStrings(rengine);                logger.info("Initializing from strings");            }            logger.info("rJava initialized");        } else {            logger.info("rjava already intialized");        }    }    private void loadRFunctions(Rengine engine) {        // File.separator is used to be system independent         // Fix me: After creating a jar file it don't work on a windwos OS        // but within eclipse it won't work on while working with '/' on windows OS        // No idea how to solve this         		// String scriptLocator = "org" + File.separator + "openscience" +		// File.separator + "cdk" + File.separator + "qsar" + File.separator +		// "model" + File.separator + "data" + File.separator + "helper.R";        String scriptLocator = "org/openscience/cdk/qsar/model/data/helper.R";        try {            File scriptFile = File.createTempFile("XXXXX", ".R");            scriptFile.deleteOnExit();            InputStreamReader reader = new InputStreamReader(                    this.getClass().getClassLoader().getResourceAsStream(scriptLocator));            BufferedReader inFile = new BufferedReader(reader);            FileWriter outFile = new FileWriter(scriptFile);            BufferedWriter outBuffer = new BufferedWriter(outFile);            String inputLine;            while ((inputLine = inFile.readLine()) != null) {                outBuffer.write(inputLine, 0, inputLine.length());                outBuffer.newLine();            }            outBuffer.close();            inFile.close();            outFile.close();            // Necessary for windows user, R needs a '/' in the path of a file even on windows            String path = scriptFile.getAbsolutePath();            path = path.replaceAll("\\\\", "/");            engine.eval("source(\"" + path + "\")");        } catch (Exception exception) {            logger.error("Could not load helper R script for JRI: ", scriptLocator);            logger.debug(exception);        }    }    private void loadRFunctionsAsStrings(Rengine evaluator) {        String[] scripts = {                "helper.R",        };        String scriptPrefix = "org/openscience/cdk/qsar/model/data/";        for (int i = 0; i < scripts.length; i++) {            String scriptLocator = scriptPrefix + scripts[i];            try {                InputStreamReader reader = new InputStreamReader(                        this.getClass().getClassLoader().getResourceAsStream(scriptLocator));                BufferedReader inFile = new BufferedReader(reader);                StringWriter sw = new StringWriter();                String inputLine;                while ((inputLine = inFile.readLine()) != null) {                    sw.write(inputLine);                    sw.write("\n");                }                sw.close();                evaluator.eval("eval(parse(text=\"" + sw.toString() + "\"))");            } catch (Exception exception) {                logger.error("Could not load CDK-rJava R scripts: ", scriptLocator);                logger.debug(exception);            }        }    }    /**     * Initializes R with the <i>--vanilla, --quiet, --slave</i> flags.     * <p/>     * This constructor will initialize the R session via a temporary file  or     * from a String depending on whether the symbol <code>initRFromString</code>     * is specified on the command line     */    public RModel() throws QSARModelException {        // check that the JRI jar and .so match        if (!Rengine.versionCheck()) {            logger.debug("API version of the JRI library does not match that of the native binary");            throw new QSARModelException("API version of the JRI library does not match that of the native binary");        }        params = new HashMap();        String[] args = {"--vanilla", "--quiet", "--slave"};        logger = new LoggingTool(this);                String initRFromString = System.getProperty("initRFromString");        boolean useDisk = true;        if (initRFromString != null && initRFromString.equals("true")) {            useDisk = false;        }        initRengine(args, useDisk);    }    /**     * Saves a R model to disk.     * <p/>     * This function can be used to save models built in a session, and then loaded     * again in a different session.     *     * @param modelName The name of the model as returned by \code{getModelName}.     * @param fileName  The file to which the model should be saved     * @throws QSARModelException if the R session cannot save the model     * @see #loadModel     */    public void saveModel(String modelName, String fileName) throws QSARModelException {        if (fileName == null || fileName.equals("")) {            fileName = modelName + ".rda";        }        rengine.assign("tmpModelName", modelName);        rengine.assign("tmpFileName", fileName);        REXP result = rengine.eval("saveModel(tmpModelName, tmpFileName)");        if (result == null) {            logger.debug("Error in 'saveModel(tmpModelName, tmpFileName)'");            throw new QSARModelException("Error saving model");        }    }    /**     * Get the name of the model.     * <p/>     * This function returns the name of the variable that the actual     * model is stored in within the R session. In general this is     * not used for the end user. In the future this might be changed     * to a private method.     *     * @return A String containing the name of the R variable     * @see #setModelName     */    public String getModelName() {        return (this.modelName);    }    /**     * Set the name of the model.     * <p/>     * Ordinarily the user does not need to call this function as each model     * is assigned a unique ID at instantiation. However, if a user saves a model     * to disk and then later loads it, the loaded     * model may overwrite a model in that session. In this situation, this method     * can be used to assign a name to the model.     *     * @param newName The name of the model     * @see #getModelName     * @see #saveModel     * @see #loadModel     */    public void setModelName(String newName) {        if (this.modelName != null && this.modelName.equals(newName)) return;        String oldName = this.modelName;        if (oldName != null) {            rengine.eval("if ('" + oldName + "' %in% ls()) {" + newName + "<-" + oldName + ";rm(" + oldName + ")}");        }        this.modelName = newName;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -