es.uvigo.ei.sing.gc.view.models.committee.evaluation.ExpertEvaluationSubtask.java Source code

Java tutorial

Introduction

Here is the source code for es.uvigo.ei.sing.gc.view.models.committee.evaluation.ExpertEvaluationSubtask.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/>.
*/
package es.uvigo.ei.sing.gc.view.models.committee.evaluation;

import java.util.Map;

import org.hibernate.Session;
import org.hibernate.Transaction;

import es.uvigo.ei.sing.ensembles.data.FeatureSubspace;
import es.uvigo.ei.sing.ensembles.evaluation.ExpertsEvaluator;
import es.uvigo.ei.sing.ensembles.training.Expert;
import es.uvigo.ei.sing.ensembles.training.IBaseClassificationProblem;
import es.uvigo.ei.sing.ensembles.training.IExpert;
import es.uvigo.ei.sing.ensembles.training.events.ExpertsEvaluationEvent;
import es.uvigo.ei.sing.ensembles.training.listeners.ExpertsEvaluationAdapter;
import es.uvigo.ei.sing.gc.execution.AbortException;
import es.uvigo.ei.sing.gc.execution.Subtask;
import es.uvigo.ei.sing.gc.execution.Task;
import es.uvigo.ei.sing.gc.model.entities.ExperimentMetaData;
import es.uvigo.ei.sing.gc.model.entities.ExpertResult;
import es.uvigo.ei.sing.gc.model.entities.SampleClassification;
import es.uvigo.ei.sing.gc.utils.HibernateUtil;
import es.uvigo.ei.sing.genomics.genensembles.GeneFeatureSet;
import es.uvigo.ei.sing.genomics.genes.GeneSet;

final class ExpertEvaluationSubtask extends ExpertsEvaluationAdapter implements Subtask<ExpertResult> {
    private static final int MAX_TRIES = 5;

    private static final long serialVersionUID = 1L;

    private final ExpertsEvaluator<?> evaluator;
    private final IExpert expert;
    private final Integer experimentId;
    private final String builderName;
    private final String geneSetId;
    private final String geneSetName;

    private Task<ExpertResult> task;
    private ExpertResult result;
    private boolean aborted;

    public ExpertEvaluationSubtask(String builderName, Integer experimentId, ExpertsEvaluator<?> evaluator,
            Map<String, String> geneSetIdToName, IBaseClassificationProblem problem)
            throws IllegalArgumentException {
        final GeneSet geneSet = ExpertEvaluationSubtask.extractProblemGeneSet(problem);

        this.geneSetId = geneSet.getName();
        this.geneSetName = geneSetIdToName.get(this.geneSetId);

        this.experimentId = experimentId;
        this.builderName = builderName;
        this.evaluator = evaluator;
        this.aborted = false;
        this.expert = new Expert(problem);
    }

    private static GeneSet extractProblemGeneSet(IBaseClassificationProblem problem)
            throws IllegalArgumentException {
        if (problem.getSubspace() instanceof FeatureSubspace) {
            final FeatureSubspace subspace = (FeatureSubspace) problem.getSubspace();

            if (subspace.getFeatureSet() instanceof GeneFeatureSet) {
                final GeneFeatureSet geneFeatureSet = (GeneFeatureSet) subspace.getFeatureSet();

                return geneFeatureSet.getGeneSet();
            } else {
                throw new IllegalArgumentException(
                        "problem.getSubspace().getFeatureSet() must be a GeneFeatureSet");
            }
        } else {
            throw new IllegalArgumentException("problem.getSubspace() must be a FeatureSubspace");
        }
    }

    private static class StorageException extends RuntimeException {
        private static final long serialVersionUID = 1L;

        public StorageException(String message) {
            super(message);
        }
    }

    private void storeResult(ExpertResult result, Integer experimentId) throws StorageException {
        synchronized (ExpertEvaluationSubtask.class) {
            boolean done = false;
            int tries = 0;
            do {
                Session session = null;
                Transaction transaction = null;
                ExperimentMetaData experiment = null;
                try {
                    this.checkAbort();

                    session = HibernateUtil.getSessionFactory().openSession();
                    transaction = session.beginTransaction();

                    this.checkAbort();

                    experiment = (ExperimentMetaData) session.load(ExperimentMetaData.class, experimentId);

                    for (SampleClassification sample : result.getSamples()) {
                        session.persist(sample);
                    }

                    this.checkAbort();

                    session.flush();
                    session.persist(result);

                    this.checkAbort();

                    session.flush();
                    experiment.getResults().add(result);

                    this.checkAbort();

                    session.update(experiment);
                    transaction.commit();

                    done = true;
                } catch (Exception e) {
                    try {
                        if (transaction != null)
                            transaction.rollback();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                    result.setId(null);
                    for (SampleClassification sample : result.getSamples()) {
                        sample.setId(null);
                    }
                    if (experiment != null)
                        experiment.getResults().remove(result);

                    if (this.aborted)
                        return;

                    e.printStackTrace();
                } finally {
                    try {
                        if (session != null && session.isOpen())
                            session.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } while (!done && ++tries < ExpertEvaluationSubtask.MAX_TRIES);

            if (!done) {
                final String message = "Evaluation result could not be stored: " + result.toString();
                System.err.println(message);
                throw new StorageException(message);
            }
        }
    }

    private void checkAbort() throws AbortException {
        if (this.aborted)
            throw new AbortException();
    }

    @Override
    public ExpertResult call() throws StorageException {
        try {
            this.checkAbort();

            this.evaluator.addExpertsEvaluationListener(this);

            this.checkAbort();

            this.evaluator.evaluateExpert(this.expert);
            this.evaluator.removeExpertsEvaluationListener(this);

            return result; // Updated through the listening methods
        } catch (AbortException ae) {
            return null;
        }
    }

    @Override
    public void expertEvaluated(ExpertsEvaluationEvent event) throws StorageException {
        if (event.getStepObject().getExpert() == this.expert) {
            this.storeResult(this.result = new ExpertResult(this.builderName, this.geneSetName, this.geneSetId,
                    event.getStepObject().getClassificationPerformance()), this.experimentId);
        }
    }

    @Override
    public void expertEvaluationAborted(ExpertsEvaluationEvent event) throws StorageException {
        if (event.getStepObject().getExpert() == this.expert) {
            final Throwable error = event.getError();

            if (error instanceof ExpertEvaluationSubtask.StorageException) {
                throw (ExpertEvaluationSubtask.StorageException) error;
            } else {
                this.storeResult(
                        this.result = new ExpertResult(this.builderName, this.geneSetName, this.geneSetId, error),
                        this.experimentId);
            }
        }
    }

    @Override
    public Task<ExpertResult> getTask() {
        return this.task;
    }

    @Override
    public void setTask(Task<ExpertResult> task) {
        this.task = task;
    }

    @Override
    public void abort() {
        this.aborted = true;
    }
}