ubic.gemma.model.association.coexpression.GeneCoexpressionNodeDegreeValueObject.java Source code

Java tutorial

Introduction

Here is the source code for ubic.gemma.model.association.coexpression.GeneCoexpressionNodeDegreeValueObject.java

Source

/*
 * The gemma project
 *
 * Copyright (c) 2014 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.model.association.coexpression;

import cern.colt.list.DoubleArrayList;
import cern.colt.list.IntArrayList;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import ubic.basecode.io.ByteArrayConverter;

import java.util.List;
import java.util.TreeMap;

/**
 * Represents a GeneCoexpressionNodeDegree
 *
 * @author Paul
 */
public class GeneCoexpressionNodeDegreeValueObject {

    private static final ByteArrayConverter bac = new ByteArrayConverter();
    private final Long geneId;
    private TreeMap<Integer, Integer> nodeDegreesNeg = new TreeMap<>();
    private TreeMap<Integer, Integer> nodeDegreesPos = new TreeMap<>();
    private TreeMap<Integer, Double> relDegreesNeg = new TreeMap<>();
    private TreeMap<Integer, Double> relDegreesPos = new TreeMap<>();

    public GeneCoexpressionNodeDegreeValueObject(GeneCoexpressionNodeDegree entity) {
        this.geneId = entity.getGeneId();
        this.initLinkCounts(entity.getLinkCountsPositive(), true);
        this.initLinkCounts(entity.getLinkCountsNegative(), false);
        this.initRelRanks(entity.getRelativeLinkRanksPositive(), true);
        this.initRelRanks(entity.getRelativeLinkRanksNegative(), false);
    }

    public double[] asDoubleArrayNegRanks() {
        return this.asDoubleArray(relDegreesNeg);
    }

    public double[] asDoubleArrayPosRanks() {
        return this.asDoubleArray(relDegreesPos);
    }

    /**
     * @return counts at each level of support, starting from 0 (which will be 0), up to the maximum support.
     */
    public int[] asIntArrayNeg() {
        return this.asIntArray(nodeDegreesNeg);
    }

    /**
     * @return counts at each level of support, starting from 0 (which will be 0), up to the maximum support.
     */
    public int[] asIntArrayPos() {
        return this.asIntArray(nodeDegreesPos);
    }

    public Long getGeneId() {
        return geneId;
    }

    /**
     * @param  support  value
     * @param  positive positive
     * @return          how many links have this much support (specifically).
     */
    public Integer getLinksWithExactSupport(Integer support, boolean positive) {
        if (positive) {
            return nodeDegreesPos.containsKey(support) ? nodeDegreesPos.get(support) : 0;
        }
        return nodeDegreesNeg.containsKey(support) ? nodeDegreesNeg.get(support) : 0;

    }

    /**
     * @param  i support
     * @return   total number of links (this is just the total of positive and negative; if some of those are with the
     *           same genes it's a double count, sorry)
     */
    public Integer getLinksWithMinimumSupport(int i) {
        return this.getLinksWithMinimumSupport(i, true) + this.getLinksWithMinimumSupport(i, false);
    }

    /**
     * @param  support  threshold
     * @param  positive positive
     * @return          how many links have at least this much support (cumulative)
     */
    public Integer getLinksWithMinimumSupport(Integer support, boolean positive) {
        assert support >= 0;
        int sum = 0;

        if (positive) {
            int maxSupportPos = this.getMaxSupportPos();
            for (Integer i = support; i <= maxSupportPos; i++) {
                sum += nodeDegreesPos.containsKey(i) ? nodeDegreesPos.get(i) : 0;
            }
        } else {
            int maxSupportNeg = this.getMaxSupportNeg();
            for (Integer i = support; i <= maxSupportNeg; i++) {
                sum += nodeDegreesNeg.containsKey(i) ? nodeDegreesNeg.get(i) : 0;
            }
        }

        return sum;
    }

    public int getMaxSupportNeg() {
        return this.nodeDegreesNeg.isEmpty() ? 0 : this.nodeDegreesNeg.lastKey();
    }

    /**
     * @return the largest value for support for this gene
     */
    @SuppressWarnings({ "unused", "WeakerAccess" }) // Possible external use
    public int getMaxSupportPos() {
        return this.nodeDegreesPos.isEmpty() ? 0 : this.nodeDegreesPos.lastKey();
    }

    public Double getRankAtMinimumSupport(Integer support, boolean positive) {
        // this can be invalid if node degree isn't updated for this gene.F
        if (positive) {
            return relDegreesPos.get(support);

        }
        return relDegreesNeg.get(support);

    }

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (this.getClass() != obj.getClass())
            return false;
        GeneCoexpressionNodeDegreeValueObject other = (GeneCoexpressionNodeDegreeValueObject) obj;
        if (geneId == null) {
            return other.geneId == null;
        }
        return geneId.equals(other.geneId);
    }

    @Override
    public String toString() {
        return "NodeDegree [geneId=" + geneId + ", nodeDegreesPos=" + StringUtils.join(nodeDegreesPos.values(), " ")
                + ", nodeDegreesNeg=" + StringUtils.join(nodeDegreesNeg.values(), " ") + "]";
    }

    public synchronized void increment(Integer support, boolean positive) {
        if (positive) {
            if (!nodeDegreesPos.containsKey(support)) {
                nodeDegreesPos.put(support, 1);
            } else {
                nodeDegreesPos.put(support, nodeDegreesPos.get(support) + 1);
            }
        } else {
            if (!nodeDegreesNeg.containsKey(support)) {
                nodeDegreesNeg.put(support, 1);
            } else {
                nodeDegreesNeg.put(support, nodeDegreesNeg.get(support) + 1);
            }
        }

    }

    /**
     * Equivalent to getLinksWithMinimumSupport( 0 )
     *
     * @return how many links this gene has in total, across all levels of support (positive and negative correlations
     *         combined)
     */
    public int total() {
        return this.getLinksWithMinimumSupport(0, true) + this.getLinksWithMinimumSupport(0, false);
    }

    /**
     * Used during recomputation only.
     */
    public void clear() {
        this.nodeDegreesNeg.clear();
        this.nodeDegreesPos.clear();
    }

    public GeneCoexpressionNodeDegree toEntity() {
        GeneCoexpressionNodeDegree r = new GeneCoexpressionNodeDegree();
        r.setGeneId(this.geneId);

        r.setRelativeLinkRanksPositive(
                GeneCoexpressionNodeDegreeValueObject.bac.doubleArrayToBytes(this.asDoubleArrayPosRanks()));
        r.setRelativeLinkRanksNegative(
                GeneCoexpressionNodeDegreeValueObject.bac.doubleArrayToBytes(this.asDoubleArrayNegRanks()));

        r.setLinkCountsPositive(GeneCoexpressionNodeDegreeValueObject.bac.intArrayToBytes(this.asIntArrayPos()));
        r.setLinkCountsNegative(GeneCoexpressionNodeDegreeValueObject.bac.intArrayToBytes(this.asIntArrayNeg()));

        return r;
    }

    private void initLinkCounts(byte[] linkCountBytes, boolean isPositive) {
        int[] byteArrayToInts = GeneCoexpressionNodeDegreeValueObject.bac.byteArrayToInts(linkCountBytes);

        if (byteArrayToInts.length < 2) {
            return;
        }

        //noinspection Duplicates // Can not extract method, arrays have diferent primitive types
        if (isPositive) {
            nodeDegreesPos = new TreeMap<>();
            for (int i = 1; i < byteArrayToInts.length; i++) {
                nodeDegreesPos.put(i, byteArrayToInts[i]);
            }
        } else {
            nodeDegreesNeg = new TreeMap<>();
            for (int i = 1; i < byteArrayToInts.length; i++) {
                nodeDegreesNeg.put(i, byteArrayToInts[i]);
            }
        }

    }

    private void initRelRanks(byte[] relativeLinkRanks, boolean isPositive) {
        double[] ranks = GeneCoexpressionNodeDegreeValueObject.bac.byteArrayToDoubles(relativeLinkRanks);

        if (ranks.length < 2) {
            return;
        }

        //noinspection Duplicates // Can not extract method, arrays have diferent primitive types
        if (isPositive) {
            relDegreesPos = new TreeMap<>();
            for (int i = 1; i < ranks.length; i++) {
                relDegreesPos.put(i, ranks[i]);
            }
        } else {
            relDegreesNeg = new TreeMap<>();
            for (int i = 1; i < ranks.length; i++) {
                relDegreesNeg.put(i, ranks[i]);
            }
        }

    }

    private double[] toPrimitive(DoubleArrayList list) {
        //noinspection unchecked
        return ArrayUtils.toPrimitive(((List<Double>) list.toList()).toArray(new Double[] {}));
    }

    private int[] toPrimitive(IntArrayList list) {
        //noinspection unchecked
        return ArrayUtils.toPrimitive(((List<Integer>) list.toList()).toArray(new Integer[] {}));
    }

    private double[] asDoubleArray(TreeMap<Integer, Double> map) {
        DoubleArrayList list = new DoubleArrayList();
        if (map.isEmpty())
            return this.toPrimitive(list);
        list.setSize(Math.max(list.size(), map.lastKey() + 1));
        for (Integer s : map.keySet()) {
            list.set(s, map.get(s));
        }

        return this.toPrimitive(list);
    }

    private int[] asIntArray(TreeMap<Integer, Integer> nodedeg) {
        IntArrayList list = new IntArrayList();
        if (nodedeg.isEmpty())
            return this.toPrimitive(list);
        Integer maxSupport = nodedeg.lastKey();
        list.setSize(maxSupport + 1);
        for (Integer s = 0; s <= maxSupport; s++) {
            if (nodedeg.containsKey(s)) {
                list.set(s, nodedeg.get(s));
            } else {
                list.set(s, 0);
            }
        }
        return this.toPrimitive(list);
    }

}