org.intermine.bio.web.displayer.MouseAllelesDisplayer.java Source code

Java tutorial

Introduction

Here is the source code for org.intermine.bio.web.displayer.MouseAllelesDisplayer.java

Source

package org.intermine.bio.web.displayer;

/*
 * Copyright (C) 2002-2016 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */

import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.intermine.api.InterMineAPI;
import org.intermine.api.query.PathQueryExecutor;
import org.intermine.api.results.ExportResultsIterator;
import org.intermine.api.results.ResultElement;
import org.intermine.metadata.FieldDescriptor;
import org.intermine.metadata.Model;
import org.intermine.model.InterMineObject;
import org.intermine.objectstore.ObjectStoreException;
import org.intermine.pathquery.Constraints;
import org.intermine.pathquery.OrderDirection;
import org.intermine.pathquery.PathQuery;
import org.intermine.web.displayer.ReportDisplayer;
import org.intermine.web.logic.config.ReportDisplayerConfig;
import org.intermine.web.logic.pathqueryresult.PathQueryResultHelper;
import org.intermine.web.logic.results.InlineResultsTable;
import org.intermine.web.logic.results.ReportObject;
import org.intermine.web.logic.session.SessionMethods;

/**
 *
 * If we are mouse, fetch results straight off of us, otherwise create a PathQuery from other
 *  organisms.
 * @author radek
 *
 */
public class MouseAllelesDisplayer extends ReportDisplayer {

    protected static final Logger LOG = Logger.getLogger(MouseAllelesDisplayer.class);

    /**
     * Construct with config and the InterMineAPI.
     * @param config to describe the report displayer
     * @param im the InterMine API
     */
    public MouseAllelesDisplayer(ReportDisplayerConfig config, InterMineAPI im) {
        super(config, im);
    }

    @SuppressWarnings({ "unchecked", "unused" })
    @Override
    public void display(HttpServletRequest request, ReportObject reportObject) {
        HttpSession session = request.getSession();
        im = SessionMethods.getInterMineAPI(session);
        Model model = im.getModel();
        PathQueryExecutor executor = im.getPathQueryExecutor(SessionMethods.getProfile(session));

        // Counts of HLPT Names
        PathQuery q = new PathQuery(model);

        Integer alleleCount = 0;
        Boolean mouser = false;
        if (!MouseAllelesDisplayer.isThisAMouser(reportObject)) {
            // to give us some homologue identifier and the actual terms to tag-cloudize
            q.addViews("Gene.symbol", "Gene.primaryIdentifier", "Gene.id",
                    "Gene.homologues.homologue.alleles.genotypes.phenotypeTerms.name");
            // add this rubbish so we do not filter out the same terms
            q.addViews("Gene.homologues.homologue.id", "Gene.homologues.homologue.alleles.id",
                    "Gene.homologues.homologue.alleles.genotypes.id");

            // mouse homologues only
            q.addConstraint(Constraints.eq("Gene.homologues.homologue.organism.shortName", "M. musculus"), "A");
            // for our gene object
            q.addConstraint(Constraints.eq("Gene.id", reportObject.getObject().getId().toString()), "B");
            // we want only those homologues that have a non-empty alleles collection
            q.addConstraint(Constraints.isNotNull("Gene.homologues.homologue.alleles.id"));
            q.setConstraintLogic("A and B");
            // order by the homologue db id, just to keep the alleles in a reasonable order
            q.addOrderBy("Gene.homologues.homologue.id", OrderDirection.ASC);

            // allele count
            PathQuery cq = new PathQuery(im.getModel());
            cq.addViews("Gene.homologues.homologue.alleles.primaryIdentifier");
            cq.addConstraint(Constraints.eq("Gene.homologues.homologue.organism.shortName", "M. musculus"), "A");
            cq.addConstraint(Constraints.eq("Gene.id", reportObject.getObject().getId().toString()), "B");
            cq.setConstraintLogic("A and B");
            try {
                alleleCount = executor.count(cq);
            } catch (ObjectStoreException e) {
                // couldn't get count
            }
        } else {
            mouser = true;

            // to give us some homologue identifier and the actual terms to tag-cloudize
            q.addViews("Gene.symbol", "Gene.primaryIdentifier", "Gene.id",
                    "Gene.alleles.genotypes.phenotypeTerms.name");
            // add this rubbish so we do not filter out the same terms
            q.addViews("Gene.alleles.id", "Gene.alleles.genotypes.id");

            // for our gene object
            q.addConstraint(Constraints.eq("Gene.id", reportObject.getObject().getId().toString()), "A");
            // we want only those homologues that have a non-empty alleles collection
            q.addConstraint(Constraints.isNotNull("Gene.alleles.id"));

            // mouser has a collection table of alleles as well
            for (FieldDescriptor fd : reportObject.getClassDescriptor().getAllFieldDescriptors()) {
                if ("alleles".equals(fd.getName()) && fd.isCollection()) {
                    // fetch the collection
                    Collection<?> collection = null;
                    try {
                        collection = (Collection<?>) reportObject.getObject().getFieldValue("alleles");
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }

                    List<Class<?>> lc = PathQueryResultHelper.queryForTypesInCollection(reportObject.getObject(),
                            "alleles", im.getObjectStore());

                    if (collection == null) {
                        return;
                    }

                    // create an InlineResultsTable
                    InlineResultsTable t = new InlineResultsTable(collection, fd.getClassDescriptor().getModel(),
                            SessionMethods.getWebConfig(request), im.getClassKeys(), collection.size(), false, lc);

                    request.setAttribute("collection", t);

                    // Get the number of alleles.
                    alleleCount = collection.size();

                    break;
                }
            }
        }

        ExportResultsIterator qResults;
        try {
            qResults = executor.execute(q);
        } catch (ObjectStoreException e) {
            throw new RuntimeException(e);
        }
        // traverse so we get a nice map from homologue symbol to a map of allele term names (and
        //  some extras)
        HashMap<String, HashMap<String, Object>> counts = new HashMap<String, HashMap<String, Object>>();
        while (qResults.hasNext()) {
            List<ResultElement> row = qResults.next();
            String sourceGeneSymbol = getIdentifier(row);
            // a per source gene map
            HashMap<String, Integer> terms;
            if (!counts.containsKey(sourceGeneSymbol)) {
                HashMap<String, Object> wrapper = new HashMap<String, Object>();
                terms = new LinkedHashMap<String, Integer>();
                wrapper.put("terms", terms);
                wrapper.put("homologueId",
                        (mouser) ? row.get(2).getField().toString() : row.get(4).getField().toString());
                wrapper.put("isMouser", mouser);
                counts.put(sourceGeneSymbol, wrapper);
            } else {
                terms = (HashMap<String, Integer>) counts.get(sourceGeneSymbol).get("terms");
            }
            // populate the allele term with count
            String alleleTerm = row.get(3).getField().toString();
            if (!alleleTerm.isEmpty()) {
                if (!terms.containsKey(alleleTerm)) {
                    terms.put(alleleTerm, 1);
                } else {
                    terms.put(alleleTerm, terms.get(alleleTerm) + 1);
                }
            }
        }

        // Now give us a map of top 20 per homologue
        HashMap<String, HashMap<String, Object>> top = new HashMap<String, HashMap<String, Object>>();
        for (String symbol : counts.keySet()) {
            HashMap<String, Object> gene = counts.get(symbol);
            LinkedHashMap<String, Integer> terms = (LinkedHashMap<String, Integer>) gene.get("terms");
            if (terms != null) {
                // sorted by value
                TreeMap<String, Integer> sorted = new TreeMap<String, Integer>(new IntegerValueComparator(terms));
                // deep copy
                for (String term : terms.keySet()) {
                    sorted.put(term, terms.get(term));
                }
                // "mark" top 20 and order by natural order - the keys
                TreeMap<String, Map<String, Object>> marked = new TreeMap<String, Map<String, Object>>();
                Integer i = 0;
                for (String term : sorted.keySet()) {
                    // wrapper map
                    HashMap<String, Object> m = new HashMap<String, Object>();
                    // am I top dog?
                    Boolean topTerm = false;
                    if (i < 20) {
                        topTerm = true;
                    }
                    m.put("top", topTerm);
                    m.put("count", sorted.get(term));
                    m.put("url", getUrl((String) gene.get("homologueId"), term));

                    // save it
                    marked.put(term, m);
                    i++;
                }

                HashMap<String, Object> wrapper = new HashMap<String, Object>();
                wrapper.put("terms", marked);
                wrapper.put("homologueId", gene.get("homologueId"));
                wrapper.put("isMouser", gene.get("isMouser"));
                top.put(symbol, wrapper);
            }
        }

        request.setAttribute("thisIsAMouser", mouser);

        request.setAttribute("counts", top);

        request.setAttribute("alleleCount", alleleCount);
    }

    private static String getUrl(String geneId, String term) {
        String url = "<query name=\"\" model=\"genomic\" view=\"Gene.alleles.genotypes."
                + "phenotypeTerms.name Gene.alleles.symbol Gene.alleles.primaryIdentifier "
                + "Gene.alleles.genotypes.name Gene.alleles.name Gene.alleles.type "
                + "Gene.alleles.genotypes.geneticBackground Gene.alleles.genotypes.zygosity "
                + "Gene.alleles.organism.name\" longDescription=\"\" " + "constraintLogic=\"B and C and A\">"
                + "<constraint path=\"Gene.alleles.genotypes.phenotypeTerms.name\" " + "code=\"B\" op=\"=\" "
                + "value=\"" + term + "\"/>" + "<constraint path=\"Gene.organism.species\" code=\"C\" op=\"=\" "
                + "value=\"musculus\"/>" + "<constraint path=\"Gene.id\" code=\"A\" op=\"=\" value=\"" + geneId
                + "\"/>" + "</query>";
        return url;
    }

    /**
     * Given columns: [symbol, primaryId, id] in a List<ResultElement> row, give us a nice
     *  identifier back
     * @param row
     * @return nice identifier
     */
    private static String getIdentifier(List<ResultElement> row) {

        String symbol = null;
        String primaryId = null;
        String id = null;

        if (row.get(0).getField() != null) {
            symbol = row.get(0).getField().toString();
            if (StringUtils.isNotEmpty(symbol)) {
                return symbol;
            }
        }

        if (row.get(1).getField() != null) {
            primaryId = row.get(1).getField().toString();
            if (StringUtils.isNotEmpty(primaryId)) {
                return primaryId;
            }
        }
        return id;
    }

    /**
     *
     * @return true if we are on a mouseified gene
     */
    private static Boolean isThisAMouser(ReportObject reportObject) {
        try {
            return "Mus".equals(
                    ((InterMineObject) reportObject.getObject().getFieldValue("organism")).getFieldValue("genus"));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * Compare Maps by their integer values
     * @author radek
     *
     */
    class IntegerValueComparator implements Comparator {

        Map base;

        /**
         * A constructor
         * @param base parameter
         */
        public IntegerValueComparator(Map base) {
            this.base = base;
        }

        /**
         * A function
         * @param a parameter
         * @param b parameter
         * @return Integer
         */
        @Override
        public int compare(Object a, Object b) {
            Integer aV = (Integer) base.get(a);
            Integer bV = (Integer) base.get(b);

            if (aV < bV) {
                return 1;
            } else {
                if (aV == bV) {
                    // Same size, need to sort by name
                    return a.toString().compareTo(b.toString());
                }
            }
            return -1;
        }
    }

}