ubic.gemma.persistence.service.expression.bioAssayData.DesignElementDataVectorDaoImpl.java Source code

Java tutorial

Introduction

Here is the source code for ubic.gemma.persistence.service.expression.bioAssayData.DesignElementDataVectorDaoImpl.java

Source

/*
 * The Gemma project.
 *
 * Copyright (c) 2006 University of British Columbia
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package ubic.gemma.persistence.service.expression.bioAssayData;

import org.apache.commons.lang3.time.StopWatch;
import org.hibernate.*;
import org.hibernate.criterion.Restrictions;
import org.hibernate.jdbc.Work;
import ubic.basecode.util.BatchIterator;
import ubic.gemma.model.common.quantitationtype.QuantitationType;
import ubic.gemma.model.expression.arrayDesign.ArrayDesign;
import ubic.gemma.model.expression.bioAssay.BioAssay;
import ubic.gemma.model.expression.bioAssayData.BioAssayDimension;
import ubic.gemma.model.expression.bioAssayData.DesignElementDataVector;
import ubic.gemma.model.expression.designElement.CompositeSequence;
import ubic.gemma.model.expression.experiment.ExpressionExperiment;
import ubic.gemma.model.genome.biosequence.BioSequence;
import ubic.gemma.persistence.service.AbstractDao;

import java.sql.Connection;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * @author pavlidis
 * @see    ubic.gemma.model.expression.bioAssayData.DesignElementDataVector
 */
public abstract class DesignElementDataVectorDaoImpl<T extends DesignElementDataVector> extends AbstractDao<T>
        implements DesignElementDataVectorDao<T> {

    DesignElementDataVectorDaoImpl(Class<T> elementClass, SessionFactory sessionFactory) {
        super(elementClass, sessionFactory);
    }

    @Override
    public final void removeRawAndProcessed(Collection<DesignElementDataVector> vectors) {
        for (DesignElementDataVector v : vectors) {
            this.getSessionFactory().getCurrentSession().delete(v);
        }
    }

    @Override
    public final Collection<DesignElementDataVector> findRawAndProcessed(BioAssayDimension dim) {
        return this.findRawAndProcessed("bioAssayDimension", dim);
    }

    @Override
    public final Collection<DesignElementDataVector> findRawAndProcessed(QuantitationType qt) {
        return this.findRawAndProcessed("quantitationType", qt);
    }

    @Override
    public void thawRawAndProcessed(Collection<DesignElementDataVector> designElementDataVectors) {
        if (designElementDataVectors == null)
            return;

        Session session = this.getSessionFactory().getCurrentSession();

        Hibernate.initialize(designElementDataVectors);

        StopWatch timer = new StopWatch();
        timer.start();
        Collection<ExpressionExperiment> ees = new HashSet<>();
        Map<BioAssayDimension, Collection<DesignElementDataVector>> dims = new HashMap<>();
        Collection<CompositeSequence> cs = new HashSet<>();
        for (DesignElementDataVector vector : designElementDataVectors) {
            session.buildLockRequest(LockOptions.NONE).lock(vector);
            Hibernate.initialize(vector);
            Hibernate.initialize(vector.getQuantitationType());

            BioAssayDimension bad = vector.getBioAssayDimension();
            if (!dims.containsKey(bad)) {
                dims.put(bad, new HashSet<DesignElementDataVector>());
            }

            dims.get(bad).add(vector);
            cs.add(vector.getDesignElement());
            ees.add(vector.getExpressionExperiment());
            session.evict(vector.getQuantitationType());
            session.evict(vector);
        }

        if (timer.getTime() > designElementDataVectors.size()) {
            AbstractDao.log.info("Thaw phase 1, " + designElementDataVectors.size() + " vectors initialized in "
                    + timer.getTime() + "ms ");
        }
        timer.reset();
        timer.start();

        // lightly thaw the EEs we saw
        for (ExpressionExperiment ee : ees) {
            Hibernate.initialize(ee);
            session.evict(ee);
        }

        if (timer.getTime() > 200) {
            AbstractDao.log.info("Thaw phase 2, " + ees.size() + " vector-associated expression experiments in "
                    + timer.getTime() + "ms ");
        }

        timer.reset();
        timer.start();

        // thaw the bioassayDimensions we saw -- usually one, more rarely two.
        for (BioAssayDimension bad : dims.keySet()) {

            BioAssayDimension tbad = (BioAssayDimension) this.getSessionFactory().getCurrentSession().createQuery(
                    "select distinct bad from BioAssayDimension bad join fetch bad.bioAssays ba join fetch ba.sampleUsed "
                            + "bm join fetch ba.arrayDesignUsed left join fetch bm.factorValues fetch all properties where bad.id= :bad ")
                    .setParameter("bad", bad.getId()).uniqueResult();

            assert tbad != null;
            assert !dims.get(tbad).isEmpty();

            for (DesignElementDataVector v : designElementDataVectors) {
                if (v.getBioAssayDimension().getId().equals(tbad.getId())) {
                    v.setBioAssayDimension(tbad);
                }
            }
        }

        if (timer.getTime() > 1000) {
            AbstractDao.log.info("Thaw phase 3, " + dims.size() + " vector-associated bioassaydimensions in "
                    + timer.getTime() + "ms ");
        }
        timer.reset();
        timer.start();

        // thaw the designelements we saw. SLOW
        long lastTime = 0;
        int count = 0;
        for (CompositeSequence de : cs) {
            BioSequence seq = de.getBiologicalCharacteristic();
            if (seq == null)
                continue;
            session.buildLockRequest(LockOptions.NONE).lock(seq);
            Hibernate.initialize(seq);

            // is this really necessary?
            ArrayDesign arrayDesign = de.getArrayDesign();
            Hibernate.initialize(arrayDesign);

            if (++count % 10000 == 0) {
                if (timer.getTime() - lastTime > 1000) {
                    AbstractDao.log
                            .info("Thawed " + count + " vector-associated probes " + timer.getTime() + " ms");
                }
                lastTime = timer.getTime();
            }
        }

        timer.stop();
        if (designElementDataVectors.size() >= 2000 || timer.getTime() > 200) {
            AbstractDao.log.info(
                    "Thaw phase 4 " + cs.size() + " vector-associated probes thawed in " + timer.getTime() + "ms");
        }
    }

    @Override
    public void thaw(Collection<T> designElementDataVectors) {
        //noinspection unchecked // Doesnt matter which implementation it is
        this.thawRawAndProcessed((Collection<DesignElementDataVector>) designElementDataVectors);
    }

    @Override
    public void thaw(T designElementDataVector) {
        Session session = this.getHibernateTemplate().getSessionFactory().getCurrentSession();
        BioSequence seq = designElementDataVector.getDesignElement().getBiologicalCharacteristic();
        if (seq != null) {
            session.buildLockRequest(LockOptions.NONE).lock(seq);
            Hibernate.initialize(seq);
        }

        ArrayDesign arrayDesign = designElementDataVector.getDesignElement().getArrayDesign();
        Hibernate.initialize(arrayDesign);

        // thaw the bioassays.
        for (BioAssay ba : designElementDataVector.getBioAssayDimension().getBioAssays()) {
            ba = (BioAssay) session.get(BioAssay.class, ba.getId());
            Hibernate.initialize(ba.getArrayDesignUsed());
            Hibernate.initialize(ba.getSampleUsed());
            Hibernate.initialize(ba.getOriginalPlatform());
        }
    }

    @Override
    public Collection<T> find(QuantitationType quantitationType) {
        return new HashSet<>(this.findByProperty("quantitationType", quantitationType));
    }

    @Override
    public Collection<T> create(final Collection<T> entities) {
        this.getSessionFactory().getCurrentSession().doWork(new Work() {
            @Override
            public void execute(Connection connection) {
                for (T entity : entities) {
                    DesignElementDataVectorDaoImpl.this.create(entity);
                }
            }
        });
        return entities;
    }

    @Override
    public void update(final Collection<T> entities) {
        this.getSessionFactory().getCurrentSession().doWork(new Work() {
            @Override
            public void execute(Connection connection) {
                for (T entity : entities) {
                    DesignElementDataVectorDaoImpl.this.update(entity);
                }
            }
        });
    }

    /**
     * @param  ee      ee
     * @param  cs2gene Map of probes to genes.
     * @return         map of vectors to gene ids.
     */
    Map<T, Collection<Long>> getVectorsForProbesInExperiments(Long ee, Map<Long, Collection<Long>> cs2gene) {

        // Do not do in clause for experiments, as it can't use the indices
        //language=HQL
        String queryString = "select dedv, dedv.designElement.id from ProcessedExpressionDataVector dedv fetch all properties"
                + " where dedv.designElement.id in ( :cs ) and dedv.expressionExperiment.id = :eeId ";

        Session session = this.getSessionFactory().getCurrentSession();
        org.hibernate.Query queryObject = session.createQuery(queryString);
        queryObject.setReadOnly(true);
        queryObject.setFlushMode(FlushMode.MANUAL);

        Map<T, Collection<Long>> dedv2genes = new HashMap<>();
        StopWatch timer = new StopWatch();
        timer.start();

        queryObject.setLong("eeId", ee);

        int batchSize = 100;
        for (Collection<Long> batch : new BatchIterator<>(cs2gene.keySet(), batchSize)) {
            this.getVectorsBatch(cs2gene, queryObject, dedv2genes, batch);
        }

        if (timer.getTime() > Math.max(200, 20 * dedv2genes.size())) {
            AbstractDao.log.info("Fetched " + dedv2genes.size() + " vectors for " + cs2gene.size() + " probes in "
                    + timer.getTime() + "ms\n" + "Vector query was: " + queryString);

        }
        return dedv2genes;
    }

    Map<T, Collection<Long>> getVectorsForProbesInExperiments(Map<Long, Collection<Long>> cs2gene) {

        //language=HQL
        String queryString = "select dedv, dedv.designElement.id from ProcessedExpressionDataVector dedv fetch all properties"
                + " where dedv.designElement.id in ( :cs ) ";

        Session session = this.getSessionFactory().getCurrentSession();
        org.hibernate.Query queryObject = session.createQuery(queryString);
        queryObject.setReadOnly(true);
        queryObject.setFlushMode(FlushMode.MANUAL);

        Map<T, Collection<Long>> dedv2genes = new HashMap<>();
        StopWatch timer = new StopWatch();
        timer.start();

        int batchSize = 100;
        for (Collection<Long> batch : new BatchIterator<>(cs2gene.keySet(), batchSize)) {
            this.getVectorsBatch(cs2gene, queryObject, dedv2genes, batch);
        }

        if (timer.getTime() > Math.max(200, 20 * dedv2genes.size())) {
            AbstractDao.log.info("Fetched " + dedv2genes.size() + " vectors for " + cs2gene.size() + " probes in "
                    + timer.getTime() + "ms\n" + "Vector query was: " + queryString);

        }
        return dedv2genes;
    }

    private Collection<DesignElementDataVector> findRawAndProcessed(String propName, Object value) {
        Criteria criteria = this.getSessionFactory().getCurrentSession()
                .createCriteria(DesignElementDataVector.class);
        criteria.add(Restrictions.eq(propName, value));
        //noinspection unchecked
        return criteria.list();
    }

    private void getVectorsBatch(Map<Long, Collection<Long>> cs2gene, org.hibernate.Query queryObject,
            Map<T, Collection<Long>> dedv2genes, Collection<Long> batch) {
        queryObject.setParameterList("cs", batch);
        queryObject.setFlushMode(FlushMode.MANUAL);
        queryObject.setReadOnly(true);
        ScrollableResults results = queryObject.scroll(ScrollMode.FORWARD_ONLY);

        while (results.next()) {
            @SuppressWarnings("unchecked")
            T dedv = (T) results.get(0);
            Long cs = (Long) results.get(1);
            Collection<Long> associatedGenes = cs2gene.get(cs);
            if (!dedv2genes.containsKey(dedv)) {
                dedv2genes.put(dedv, associatedGenes);
            } else {
                Collection<Long> mappedGenes = dedv2genes.get(dedv);
                mappedGenes.addAll(associatedGenes);
            }
        }

        results.close();
    }

}