/*
* The MIT License (MIT)
*
* Copyright (c) 2007-2015 Broad Institute
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.broad.igv.tools;
import org.broad.igv.track.WindowFunction;
import org.junit.Before;
import org.junit.Test;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
/**
* @author jrobinso
*/
public class AccumulatorTest {
protected final int numberOfPoints = (int) 1e6;
private List<WindowFunction> wfs;
private Map<WindowFunction, Double> values;
public AccumulatorTest() {
}
@Before
public void setUp() throws Exception {
wfs = Arrays.asList(
WindowFunction.min,
WindowFunction.percentile90,
WindowFunction.percentile10,
WindowFunction.mean,
WindowFunction.median,
WindowFunction.max,
WindowFunction.count,
WindowFunction.percentile2,
WindowFunction.percentile98);
values = new HashMap<WindowFunction, Double>();
values.put(WindowFunction.min, 0.0);
values.put(WindowFunction.percentile90, 0.9);
values.put(WindowFunction.percentile10, 0.1);
values.put(WindowFunction.mean, 0.5);
values.put(WindowFunction.median, 0.5);
values.put(WindowFunction.max, 1.0);
values.put(WindowFunction.count, (double) numberOfPoints);
values.put(WindowFunction.percentile2, 0.02);
values.put(WindowFunction.percentile98, 0.98);
}
/**
* Test calculation of all percentiles
*/
@Test
public void testAll() {
// Compute stats for large number of points
ListAccumulator accum = new ListAccumulator(wfs);
for (int i = 0; i < numberOfPoints; i++) {
accum.add(1, (float) Math.random());
}
accum.finish();
for (WindowFunction wf : wfs) {
double v = accum.getValue(wf);
assertEquals(wf.getValue(), values.get(wf), v, 1.0e-2);
}
}
/**
* Pathological case, all zeroes
*/
@Test
public void testZeroes() {
// Takes too long to use all 1e6 points
// Percentile.select is slow when all elements are the same (apparently)
ListAccumulator accum = new ListAccumulator(wfs);
for (int i = 0; i < 200001; i++) {
accum.add(1, 0);
}
accum.finish();
for (WindowFunction wf : wfs) {
if (wf != WindowFunction.count) {
double v = accum.getValue(wf);
assertEquals(wf.getValue(), 0, v, 1.0e-2);
}
}
}
/**
* Pathological case, empty accumulator
*/
@Test
public void testEmpty() {
ListAccumulator accum = new ListAccumulator(wfs);
accum.finish();
for (WindowFunction wf : wfs) {
if (wf != WindowFunction.count) {
float v = accum.getValue(wf);
assertTrue(wf.getValue(), Float.isNaN(v));
}
}
}
/**
* Pathological case, all NaN
*/
@Test
public void testNaN() {
ListAccumulator accum = new ListAccumulator(wfs);
for (int i = 0; i < 1000; i++) {
accum.add(1, Float.NaN);
}
accum.finish();
for (WindowFunction wf : wfs) {
if (wf != WindowFunction.count) {
float v = accum.getValue(wf);
assertTrue(wf.getValue(), Float.isNaN(v));
}
}
}
/**
* A single NaN
*/
@Test
public void testSingleNaN() {
ListAccumulator accum = new ListAccumulator(wfs);
accum.add(1, Float.NaN);
accum.finish();
for (WindowFunction wf : wfs) {
if (wf != WindowFunction.count) {
float v = accum.getValue(wf);
assertTrue(wf.getValue(), Float.isNaN(v));
}
}
}
/**
* Pathological case, # of data points exactly equals percentile chunk size
*/
@Test
public void testChunkSize() {
ListAccumulator accum = new ListAccumulator(wfs);
for (int i = 0; i < ListAccumulator.MAX_VALUE_COUNT; i++) {
accum.add(1, (float) Math.random());
}
accum.finish();
for (WindowFunction wf : wfs) {
double v = accum.getValue(wf);
if (wf == WindowFunction.count) {
assertEquals(wf.getValue(), ListAccumulator.MAX_VALUE_COUNT, v, 1.0e-2);
} else {
assertEquals(wf.getValue(), values.get(wf), v, 1.0e-2);
}
}
accum = new ListAccumulator(wfs);
for (int i = 0; i < ListAccumulator.MAX_VALUE_COUNT - 1; i++) {
accum.add(1, (float) Math.random());
}
accum.finish();
for (WindowFunction wf : wfs) {
double v = accum.getValue(wf);
if (wf == WindowFunction.count) {
assertEquals(wf.getValue(), ListAccumulator.MAX_VALUE_COUNT - 1, v, 1.0e-2);
} else {
assertEquals(wf.getValue(), values.get(wf), v, 1.0e-2);
}
}
accum = new ListAccumulator(wfs);
for (int i = 0; i < ListAccumulator.MAX_VALUE_COUNT + 1; i++) {
accum.add(1, (float) Math.random());
}
accum.finish();
for (WindowFunction wf : wfs) {
double v = accum.getValue(wf);
if (wf == WindowFunction.count) {
assertEquals(wf.getValue(), ListAccumulator.MAX_VALUE_COUNT + 1, v, 1.0e-2);
} else {
assertEquals(wf.getValue(), values.get(wf), v, 1.0e-2);
}
}
}
}