All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.maizegenetics.dna.map.PositionListBuilder Maven / Gradle / Ivy

package net.maizegenetics.dna.map;

import cern.colt.GenericSorting;
import cern.colt.Swapper;
import cern.colt.function.IntComparator;
import com.google.common.base.Preconditions;
import net.maizegenetics.dna.snp.genotypecall.GenotypeCallTableBuilder;
import net.maizegenetics.util.Tuple;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * A builder for creating immutable PositionList.
 *
 * 

* Example: *

   {@code
 *   PositionListBuilder b=new PositionArrayList.Builder();
 *   for (int i = 0; i 

* If being built separately from the genotypes, then use validate ordering to make sure sites are added in the * intended order. This list WILL be sorted. *

Builder instances can be reused - it is safe to call {@link #build()} * multiple times to build multiple lists in series. Each new list * contains the one created before it. * *

Builder instances can be reused - it is safe to call {@link #build()} */ public class PositionListBuilder { private static final Logger myLogger = LogManager.getLogger(PositionListBuilder.class); private ArrayList myPositions = new ArrayList<>(); private String genomeVersion = null; /** * Creates a new builder. The returned builder is equivalent to the builder * generated by {@link }. */ public PositionListBuilder() { } /** * Creates a new builder with a given number of Positions. This is most * useful when the number of sites is known from the beginning and the set * method will be used to set positions perhaps out of order. Useful in * multithreaded builders. */ public PositionListBuilder(int numberOfPositions) { for (int i = 0; i < numberOfPositions; i++) { myPositions.add(new GeneralPosition.Builder(Chromosome.UNKNOWN, i).build()); } } public boolean contains(Position pos) { return myPositions.contains(pos); } /** * Adds {@code element} to the {@code PositionList}. * * @param element the element to add * * @return this {@code Builder} object * @throws NullPointerException if {@code element} is null */ public PositionListBuilder add(Position element) { Preconditions.checkNotNull(element, "element cannot be null"); myPositions.add(element); return this; } /** * Adds each element of {@code elements} to the {@code PositionList}. * * @param collection collection containing positions to be added to this * list * * @return this {@code Builder} object * @throws NullPointerException if {@code elements} is or contains null */ public PositionListBuilder addAll(Collection collection) { myPositions.ensureCapacity(myPositions.size() + collection.size()); for (Position elem : collection) { Preconditions.checkNotNull(elem, "elements contains a null"); myPositions.add(elem); } return this; } public PositionListBuilder addAll(PositionListBuilder builder) { myPositions.ensureCapacity(myPositions.size() + builder.size()); for (Position elem : builder.myPositions) { Preconditions.checkNotNull(elem, "elements contains a null"); myPositions.add(elem); } return this; } /** * Replaces the element at the specified position in this list with the * specified element. * * @param index index of the element to replace * @param element element to be stored at the specified position * * @return this {@code Builder} object */ public PositionListBuilder set(int index, Position element) { myPositions.set(index, element); return this; } public PositionListBuilder genomeVersion(String genomeVersion) { this.genomeVersion = genomeVersion; return this; } /** * Returns whether List is already ordered. Important to check this if * genotype and sites are separately built, as the PositionArrayList must be * sorted, and will be with build. */ public boolean validateOrdering() { boolean result = true; Position startAP = myPositions.get(0); for (Position ap : myPositions) { if (ap.compareTo(startAP) < 0) { myLogger.warn("validateOrdering: " + ap.toString() + " and " + startAP.toString() + " out of order."); return false; } startAP = ap; } return result; } /** * Returns the size (number of positions) in the current list * * @return current size */ public int size() { return myPositions.size(); } /** * Generates a generic position list when no position information known * * @param numSites number of sites * * @return generic position list */ public static PositionList getInstance(int numSites) { PositionListBuilder builder = new PositionListBuilder(); for (int i = 0; i < numSites; i++) { builder.add(new GeneralPosition.Builder(Chromosome.UNKNOWN, i).build()); } return builder.build(); } /** * Creates in memory of PositionList from the an array of positions. */ public static PositionList getInstance(List positions) { PositionListBuilder builder = new PositionListBuilder(); builder.addAll(positions); return builder.build(); } /** * Returns a newly-created {@code ImmutableList} based on the myPositions of * the {@code Builder}. */ public PositionList build() { Collections.sort(myPositions); return new PositionArrayList(myPositions, genomeVersion); } public Tuple buildWithSiteRedirect() { int[] siteRedirect = sort(); PositionList positions = new PositionArrayList(myPositions, genomeVersion); return new Tuple<>(positions, siteRedirect); } public PositionList build(GenotypeCallTableBuilder genotypes) { sortPositions(genotypes); return new PositionArrayList(myPositions, genomeVersion); } public PositionListBuilder sortPositions(GenotypeCallTableBuilder genotypes) { int numPositions = myPositions.size(); if (numPositions != genotypes.getSiteCount()) { throw new IllegalArgumentException("PositionListBuilder: sortPositions: position list size: " + numPositions + " doesn't match genotypes num position: " + genotypes.getSiteCount()); } genotypes.reorderPositions(sort()); return this; } public PositionListBuilder sortPositions() { sort(); return this; } public int[] sort() { int numPositions = myPositions.size(); final int indicesOfSortByPosition[] = new int[numPositions]; for (int i = 0; i < indicesOfSortByPosition.length; i++) { indicesOfSortByPosition[i] = i; } Swapper swapPosition = new Swapper() { @Override public void swap(int a, int b) { int temp = indicesOfSortByPosition[a]; indicesOfSortByPosition[a] = indicesOfSortByPosition[b]; indicesOfSortByPosition[b] = temp; } }; IntComparator compPosition = new IntComparator() { @Override public int compare(int a, int b) { return myPositions.get(indicesOfSortByPosition[a]).compareTo(myPositions.get(indicesOfSortByPosition[b])); } }; GenericSorting.quickSort(0, indicesOfSortByPosition.length, compPosition, swapPosition); ArrayList temp = new ArrayList<>(numPositions); for (int t = 0; t < numPositions; t++) { temp.add(myPositions.get(indicesOfSortByPosition[t])); } myPositions = temp; return indicesOfSortByPosition; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy