fr.ens.transcriptome.corsen.calc.CorsenHistoryResults.java Source code

Java tutorial

Introduction

Here is the source code for fr.ens.transcriptome.corsen.calc.CorsenHistoryResults.java

Source

/*
 *                  Corsen development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU General Public Licence version 2 or later. This
 * should be distributed with the code. If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/licenses/gpl-2.0.txt
 *
 * Copyright for this code is held jointly by the microarray platform
 * of the cole Normale Suprieure and the individual authors.
 * These should be listed in @author doc comments.
 *
 * For more information on the Corsen project and its aims,
 * or to join the Corsen google group, visit the home page
 * at:
 *
 *      http://transcriptome.ens.fr/corsen
 *
 */

package fr.ens.transcriptome.corsen.calc;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.apache.commons.math.stat.descriptive.moment.Mean;
import org.apache.commons.math.stat.descriptive.rank.Median;

import fr.ens.transcriptome.corsen.model.Particle3D;

/**
 * This class handle last corsen results.
 * @author Laurent Jourdren
 */
public final class CorsenHistoryResults {

    private static CorsenHistoryResults singleton = new CorsenHistoryResults();

    private Map<String, Entry> entries = new LinkedHashMap<String, Entry>();
    private List<String> keys = new ArrayList<String>();

    private static int count = 0;

    private Map<StatType, double[]> data = new HashMap<StatType, double[]>();
    private StatType statType = CorsenHistoryResults.StatType.values()[0];

    private CompiledScript script;

    public enum StatType {

        MEDIAN("median"), MEAN("mean"), MIN("min"), MAX("max"), CUSTOM("custom");

        private String description;

        /**
         * Get the description of the type of stat.
         * @return the description of the stat
         */
        public String toString() {

            return this.description;
        }

        /**
         * Get a Stat type from this description.
         * @param description description of the type
         * @return a StatType
         */
        public static StatType getTypeFromDescription(final String description) {

            if (description == null)
                return null;

            StatType[] types = StatType.values();

            for (int i = 0; i < types.length; i++) {

                if (description.equals(types[i].toString()))
                    return types[i];
            }

            return null;
        }

        //
        // Constructor
        //

        /**
         * Private constructor.
         * @param description The description of the stat
         */
        private StatType(final String description) {

            this.description = description;

        }

    };

    /**
     * Define an entry of the last corsen results.
     * @author Laurent Jourdren
     */
    public static final class Entry {

        private int id = count++;
        private File fileA;
        private File fileB;
        private File resultsPath;
        private double medianMinDistance;
        private double meanMinDistance;
        private double minMinDistance;
        private double maxMinDistance;
        private double customMinDistance;

        /**
         * Get the id of the entry.
         * @return the id of the entry
         */
        public int getId() {

            return this.id;
        }

        /**
         * Get File A.
         * @return the file A
         */
        public File getFileA() {

            return this.fileA;
        }

        /**
         * Get File B.
         * @return the file B
         */
        public File getFileB() {

            return this.fileB;
        }

        /**
         * Get the result path.
         * @return the result path
         */
        public File getResultsPath() {

            return this.resultsPath;
        }

        /**
         * Get median of the min distances.
         * @return the median of the median distances.
         */
        public double getMedianMinDistance() {

            return this.medianMinDistance;
        }

        /**
         * Get mean of the min distances.
         * @return the mean of the min distances.
         */
        public double getMeanMinDistance() {

            return this.meanMinDistance;
        }

        /**
         * Get the min of the min distances.
         * @return the min of the min distances.
         */
        public double getMinMinDistance() {

            return this.minMinDistance;
        }

        /**
         * Get the max of the min distances.
         * @return the max of the min distances.
         */
        public double getMaxMinDistance() {

            return this.maxMinDistance;
        }

        /**
         * Get custom min distances.
         * @return the custom min distances.
         */
        public double getCustomMinDistance() {

            return this.customMinDistance;
        }

        /**
         * Set the custom value
         * @param customValue Value to set
         */
        private void setCustom(final double customValue) {

            this.customMinDistance = customValue;
        }

        private Entry(final File fileA, final File fileB, final CorsenResult cr) {

            // final double dist = cr.getMinAnalyser().getMedian();
            final DistanceAnalyser da = cr.getMinAnalyser();

            this.fileA = fileA;
            this.fileB = fileB;
            this.resultsPath = cr.getResultsPath();
            this.medianMinDistance = da.getMedian();
            this.meanMinDistance = da.getMean();
            this.minMinDistance = da.getMin();
            this.maxMinDistance = da.getMax();
        }

    }

    /**
     * Get the stat type.
     * @return The stat type
     */
    public StatType getStatType() {

        return statType;
    }

    /**
     * Set the statType
     * @param statType StatType to set
     */
    public void setStatType(final StatType statType) {

        this.statType = statType;
    }

    /**
     * Add a result to the results.
     * @param cr Corsen result to add
     */
    public void addResult(final CorsenResult cr) {

        if (cr == null)
            return;

        final File fileA = cr.getMessengersFile();
        final File fileB = cr.getMitosFile();

        final String key = fileA.getAbsolutePath() + "-" + fileB.getAbsolutePath();

        if (this.entries.containsKey(key))
            this.keys.remove(key);

        final Entry e = new Entry(fileA, fileB, cr);
        e.setCustom(calcCustomValue(cr));

        this.entries.put(key, e);
        this.keys.add(key);

        this.data.clear();
    }

    /**
     * Clear the entries.
     */
    public void clear() {

        this.entries.clear();
        this.keys.clear();
        this.data.clear();
    }

    /**
     * Get the number of entries.
     * @return The number of entries
     */
    public int size() {

        return this.entries.size();
    }

    /**
     * Remove an entry
     * @param index index of the element to get
     */
    public void remove(final int index) {

        String key = this.keys.get(index);

        this.entries.remove(key);
        this.keys.remove(index);

        this.data.clear();
    }

    /**
     * Get an entry
     * @param index Index of the entry to get
     * @return an entry
     */
    public Entry get(final int index) {

        final String key = this.keys.get(index);

        return this.entries.get(key);
    }

    /**
     * Get an array of the minimal distances
     * @return an array of the minimal distances
     */
    public double[] getDistances() {

        if (data.containsKey(this.statType))
            return this.data.get(this.statType);

        final double[] data = new double[size()];

        int count = 0;
        for (Map.Entry<String, Entry> e : this.entries.entrySet()) {

            final double value;

            switch (this.statType) {

            case MEAN:
                value = e.getValue().getMeanMinDistance();
                break;

            case MIN:
                value = e.getValue().getMinMinDistance();
                break;

            case MAX:
                value = e.getValue().getMaxMinDistance();
                break;

            case CUSTOM:
                value = e.getValue().getCustomMinDistance();
                break;

            case MEDIAN:
            default:
                value = e.getValue().getMedianMinDistance();
                break;

            }

            data[count++] = value;
        }

        this.data.put(this.statType, data);

        return data;
    }

    /**
     * Get the median of the median of Min Distances.
     * @return thee median of the median of Min Distances
     */
    public double getMedianOfMedianMinDistances() {

        return new Median().evaluate(getDistances());
    }

    /**
     * Get the mean of the median of Min Distances.
     * @return thee mean of the median of Min Distances
     */
    public double getMeanOfMedianMinDistances() {

        return new Mean().evaluate(getDistances());
    }

    /**
     * Set the custom expression
     * @param expression The expression to set
     * @return true if the expression is correct
     */
    public boolean setCustomExpression(final String expression) {

        this.script = null;

        if (expression == null || "".equals(expression.trim()))
            return true;

        ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");

        Compilable compilable = (Compilable) engine;

        try {

            final CompiledScript script = compilable.compile(expression);
            this.script = script;

        } catch (ScriptException e) {

            return false;
        }

        return true;
    }

    /**
     * Calc the custom value.
     * @param cr CorsenResults
     * @return the custom value
     */
    private double calcCustomValue(final CorsenResult cr) {

        if (this.script == null)
            return Double.NaN;

        Map<Particle3D, Distance> in = cr.getMinDistances();

        long inCount = 0;
        long outCount = 0;

        for (Map.Entry<Particle3D, Distance> e : in.entrySet()) {

            final Particle3D particle = e.getKey();
            final long intensity = particle.getIntensity();
            final Distance distance = e.getValue();

            inCount += intensity;

            final Bindings b = this.script.getEngine().getBindings(ScriptContext.ENGINE_SCOPE);

            b.put("i", intensity);
            b.put("d", distance.getDistance());

            try {

                Object o = this.script.eval();

                if (o instanceof Boolean && ((Boolean) o) == true)
                    outCount += intensity;

            } catch (ScriptException e1) {
            }
        }

        return (double) outCount / (double) inCount;
    }

    //
    // Singleton
    //

    /**
     * Get the singleton.
     * @return the CorsenHistoryResults object
     */
    public static CorsenHistoryResults getCorsenHistoryResults() {

        return singleton;
    }

    //
    // Constructor
    //

    private CorsenHistoryResults() {
    }

}