es.uvigo.ei.sing.gc.model.entities.ExpertResult.java Source code

Java tutorial

Introduction

Here is the source code for es.uvigo.ei.sing.gc.model.entities.ExpertResult.java

Source

/*
   This file is part of GeneCommittee.
    
   GeneCommittee 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.
    
   GeneCommittee 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 GeneCommittee.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 *   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/>.
 */
package es.uvigo.ei.sing.gc.model.entities;

import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.apache.commons.lang.SerializationUtils;

import es.uvigo.ei.sing.datatypes.validation.ClassificationPerformance;
import es.uvigo.ei.sing.datatypes.validation.DefaultClassificationPerformance;
import es.uvigo.ei.sing.datatypes.validation.DefaultMultiStepClassificationPerformance;
import es.uvigo.ei.sing.datatypes.validation.MultiStepClassificationPerformance;

/**
 *
 * @author Miguel Reboiro-Jato
 *
 */
@Entity
public class ExpertResult {
    @Id
    @GeneratedValue
    private Integer id;

    @Column
    private String classifierName;
    @Column
    private String geneSetName;
    @Column
    private String geneSetId;
    @Column(nullable = false)
    private boolean selected;

    @Transient
    private ClassificationPerformance performance;

    private byte[] abortCause;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    @JoinColumn(name = "expertResult_id")
    @Column(nullable = true)
    private Set<SampleClassification> samples;

    public ExpertResult() {
    }

    public ExpertResult(String classifierName, String geneSetName, String geneSetId, Throwable abortCause) {
        this.abortCause = SerializationUtils.serialize(abortCause);
        this.performance = null;

        this.classifierName = classifierName;
        this.geneSetName = geneSetName;
        this.geneSetId = geneSetId;
        this.selected = false;

        this.samples = new HashSet<SampleClassification>();
    }

    public ExpertResult(String classifierName, String geneSetName, String geneSetId,
            ClassificationPerformance performance) {
        this.abortCause = null;
        this.performance = performance;

        this.classifierName = classifierName;
        this.geneSetName = geneSetName;
        this.geneSetId = geneSetId;
        this.selected = false;

        this.samples = ExpertResult.extractSampleClassification(performance);
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Set<SampleClassification> getSamples() {
        return samples;
    }

    public void setSamples(Set<SampleClassification> samples) {
        this.samples = samples;
    }

    private synchronized void initClassificationPerformance() {
        if (this.performance == null && this.samples != null && !this.samples.isEmpty()) {
            final Set<Object> classes = new HashSet<Object>();
            Boolean multi = null;
            for (SampleClassification sample : this.samples) {
                if (multi == null) {
                    multi = sample.isMultiStep();
                } else if (multi != sample.isMultiStep()) {
                    throw new IllegalStateException("Different sample types");
                }

                classes.add(sample.getRealClass());
            }

            final Object[] classArray = classes.toArray(new Object[classes.size()]);
            if (multi) {
                final SortedMap<Integer, List<SampleClassification>> sampleMap = new TreeMap<Integer, List<SampleClassification>>();

                for (SampleClassification sample : this.samples) {
                    if (!sampleMap.containsKey(sample.getStep())) {
                        sampleMap.put(sample.getStep(), new LinkedList<SampleClassification>());
                    }

                    sampleMap.get(sample.getStep()).add(sample);
                }

                for (Map.Entry<Integer, List<SampleClassification>> entry : sampleMap.entrySet()) {
                    if (this.performance == null) {
                        this.performance = new DefaultMultiStepClassificationPerformance(
                                ExpertResult.createClassificationPerformance(
                                        Integer.toString(this.getId()) + "-Step " + entry.getKey(), classArray,
                                        entry.getValue()));
                    } else {
                        this.performance = this.performance.merge(ExpertResult.createClassificationPerformance(
                                Integer.toString(this.getId()) + "-Step " + entry.getKey(), classArray,
                                entry.getValue()));
                    }
                }
            } else {
                this.performance = ExpertResult.createClassificationPerformance(Integer.toString(this.getId()),
                        classArray, samples);
            }
        }
    }

    private final static Set<SampleClassification> extractSampleClassification(
            ClassificationPerformance performance) {
        final Set<SampleClassification> samples = new HashSet<SampleClassification>();

        if (performance instanceof MultiStepClassificationPerformance
                && ((MultiStepClassificationPerformance) performance).numSteps() > 1) {
            final MultiStepClassificationPerformance msPerformance = (MultiStepClassificationPerformance) performance;

            for (int i = 0; i < msPerformance.numSteps(); i++) {
                final ClassificationPerformance stepPerformance = msPerformance.getStepPerformance(i);

                final Set<SampleClassification> stepSamples = ExpertResult
                        .extractSampleClassification(stepPerformance);
                for (SampleClassification sample : stepSamples) {
                    sample.setStep(i);
                }

                samples.addAll(stepSamples);
            }
        } else {
            for (Object key : performance.getClassesKeys()) {
                samples.add(
                        new SampleClassification(key.toString(), performance.getRealClasses().get(key).toString(),
                                performance.getPredictedClasses().get(key).toString()));
            }
        }

        return samples;
    }

    private final static ClassificationPerformance createClassificationPerformance(String name, Object[] classes,
            Collection<SampleClassification> samples) {
        final Map<Object, Object> realClasses = new HashMap<Object, Object>();
        final Map<Object, Object> predictedClasses = new HashMap<Object, Object>();

        for (SampleClassification sample : samples) {
            predictedClasses.put(sample.getSampleId(), sample.getPredictedClass());
            realClasses.put(sample.getSampleId(), sample.getRealClass());
        }

        return new DefaultClassificationPerformance(name, classes, predictedClasses, realClasses);
    }

    @Transient
    public Throwable getAbortCause() {
        if (this.abortCause == null) {
            return null;
        } else {
            return (Throwable) SerializationUtils.deserialize(this.abortCause);
        }
    }

    @Column(name = "abortCause", length = 1048576, nullable = true)
    @Lob
    @Access(AccessType.PROPERTY)
    private void setSerializedAbortCause(byte[] abortCause) {
        this.abortCause = abortCause;
    }

    @SuppressWarnings("unused")
    private byte[] getSerializedAbortCause() {
        return this.abortCause;
    }

    /**
     * @return the classifierName
     */
    public String getClassifierName() {
        return classifierName;
    }

    /**
     * @param classifierName the classifierName to set
     */
    public void setClassifierName(String classifierName) {
        this.classifierName = classifierName;
    }

    /**
     * @return the geneSetName
     */
    public String getGeneSetName() {
        return geneSetName;
    }

    /**
     * @param geneSetName the geneSetName to set
     */
    public void setGeneSetName(String geneSetName) {
        this.geneSetName = geneSetName;
    }

    /**
     * @return the selected
     */
    public boolean isSelected() {
        return selected;
    }

    /**
     * @param selected the selected to set
     */
    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    /**
     * @return the geneSetId
     */
    public String getGeneSetId() {
        return geneSetId;
    }

    /**
     * @param geneSetId the geneSetId to set
     */
    public void setGeneSetId(String geneSetId) {
        this.geneSetId = geneSetId;
    }

    public ClassificationPerformance getClassificationPerformance() {
        if (this.performance == null) {
            this.initClassificationPerformance();
        }
        return this.performance;
    }

    public MultiStepClassificationPerformance getMultiStepClassificationPerformance() {
        return (MultiStepClassificationPerformance) this.getClassificationPerformance();
    }

    public boolean isAborted() {
        return this.getAbortCause() != null;
    }

    public boolean isPerformance() {
        return this.getClassificationPerformance() != null;
    }

    public boolean isSinglePerformance() {
        return this.isPerformance()
                && !(this.getClassificationPerformance() instanceof MultiStepClassificationPerformance);
    }

    public boolean isMultiStepPerformance() {
        return this.isPerformance()
                && this.getClassificationPerformance() instanceof MultiStepClassificationPerformance;
    }

    public static class ExpertResultMetaDataComparator implements Comparator<ExpertResult> {
        @Override
        public int compare(ExpertResult o1, ExpertResult o2) {
            final int cmpName = o1.toString().compareToIgnoreCase(o2.toString());

            if (cmpName == 0) {
                return o1.getId() - o2.getId();
            } else {
                return cmpName;
            }
        }
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (!(obj instanceof ExpertResult)) {
            return false;
        }
        ExpertResult other = (ExpertResult) obj;
        if (getId() == null) {
            if (other.getId() != null) {
                return false;
            }
        } else if (!getId().equals(other.getId())) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return this.classifierName + " # " + this.geneSetName;
    }
}