Skip to content

Commit

Permalink
initial commit of code - migrated from groovy-ngs-utils + relicensed …
Browse files Browse the repository at this point in the history
…to Apache 2.0 license
  • Loading branch information
ssadedin committed Jul 19, 2014
1 parent f069d8c commit 90d80a1
Show file tree
Hide file tree
Showing 13 changed files with 2,147 additions and 0 deletions.
3 changes: 3 additions & 0 deletions NOTICE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Graxxia, Groovy Maths Utils
Copyright 2014, Simon Sadedin and Contributing Authors

47 changes: 47 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
apply plugin: 'groovy'

VERSION="0.0.1"
STAGE="build/stage/graxxia-$VERSION"

repositories {
mavenCentral()
}

configurations {
compile
}

dependencies {
groovy group: 'org.codehaus.groovy', name: 'groovy', version: '2.1.0'
groovy group: 'org.apache.ivy', name:'ivy', version:'2.2.0'
groovy 'com.lowagie:itext:2.1.7'
groovy 'org.apache.commons:commons-math3:3.0'
groovy 'junit:junit:4.4'
groovy 'commons-cli:commons-cli:1.1'
groovy 'com.xlson.groovycsv:groovycsv:1.0'
groovy 'log4j:log4j:1.2.17'
compile files(fileTree(dir:'lib', includes:['*.jar']))
}

// Bundle all dependencies into output library
jar {
from configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
exclude "groovy/**"
exclude "org/codehaus/**"
exclude "META-INF/groovy*"
exclude "META-INF/**/*groovy*"
exclude "META-INF/BCKEY*"
exclude "org/bouncycastle/**"
}

groovydoc {

}

task doc << {
groovydoc {
packageNames = ['']
destinationDir = new File('doc')
source = 'src/main/groovy'
}
}
182 changes: 182 additions & 0 deletions src/main/groovy/graxxia/Drawing.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/*
* Graxxia - Groovy Maths Utililities
*
* Copyright (C) 2014 Simon Sadedin, ssadedin<at>gmail.com and contributors.
*
* This file is licensed under the Apache Software License Version 2.0.
* For the avoidance of doubt, it may be alternatively licensed under GPLv2.0
* and GPLv3.0. Please see LICENSE.txt in your distribution directory for
* further details.
*/
package graxxia

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.image.BufferedImage;
import javax.imageio.*
/**
* A very simple class to support a simple drawing canvas and make it easy to map
* a mathematical space on to the drawing canvas.
*
* @author Simon
*/
class Drawing {

BufferedImage image = null;
Graphics2D g = null
String fileName = null

List<String> operations = []

int xOffset = 0
int yOffset = 0

double maxX = 0
double maxY = 0
double minX = 0
double minY = 0

double xScale = 1.0d
double yScale = 1.0d

int height = -1
int width = -1

boolean log = false

public Drawing(String fileName, int width, int height, double minX, double minY, double maxX, double maxY) {
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
this.g = image.createGraphics()
this.fileName = fileName
this.xScale = width / (maxX - minX)
this.yScale = width / (maxY - minY) // invert Y so it is like math plotting coordinates
this.xOffset = -minX
this.yOffset = -minY
this.height = height
this.width = width
g.setBackground(Color.WHITE)
g.clearRect(0,0,width,height)
color(0,0,0)
}

public Drawing(String fileName, int width, int height) {
this(fileName,width,height,0,0, 1.0d, 1.0d)
}

/**
* Adjust xScale and yScale to fit the given point inside
* the bounds
*/
void rescale(double x1, double y1, double x2, double y2) {

}

Drawing bars(def x1, def x2, def y) {
lines(x1,y,x2,y,bars:true)
}

Drawing bars(IntRange range, def y) {
lines(range.from, range.to,y,bars:true)
}

Drawing lines(Map options=[:], def x1, def y1, def x2, def y2) {
if(x1.size() != y1.size())
throw new IllegalArgumentException("Size of x1 (${x1.size()} different to size of y1 ${y1.size()}")

if(x2.size() != y2.size())
throw new IllegalArgumentException("Size of x2 (${x2.size()} different to size of y2 ${y2.size()}")

x1.eachWithIndex { x, index ->
if(options.color)
color(options.color)

def txed = txLine(x, y1[index], x2[index], y2[index])
if(options.bars) {
drawBar(txed)
}
}
save()
return this
}

private void drawBar(lineCoords) {
g.drawLine((int)lineCoords[0],(int)lineCoords[1]-5,(int)lineCoords[0],(int)lineCoords[1]+5)
g.drawLine((int)lineCoords[2],(int)lineCoords[3]-5,(int)lineCoords[2],(int)lineCoords[3]+5)
}

Drawing line(def x1, def y1, def x2, def y2) {
txLine(x1,y1,x2,y2)
save()
return this
}

Drawing color(String value) {
Color colorVal = Color[value]
g.setPaint(colorVal)
return this
}

Drawing color(int red, int green, int blue) {
g.setPaint(new Color(red,green,blue))
return this
}

List<Double> txLine(double x1, double y1, double x2, double y2) {
x1 = xScale * (xOffset + x1)
x2 = xScale * (xOffset + x2)
y1 = this.height - yScale * (yOffset + y1)
y2 = this.height - yScale * (yOffset + y2)

if(log)
println "Drawing line ($x1,$y1) - ($x2,$y2)"
g.drawLine((int)x1, (int)y1, (int)x2, (int)y2)
[x1,y1,x2,y2]
}

void save() {
ImageIO.write(image, "png", new File(fileName));
}

Drawing text(def x, def double y, def value) {
x = x.toDouble()
y = y.toDouble()
value = String.valueOf(value)
x = xScale * (xOffset + x)
y = this.height - yScale * (yOffset + y)
if(log)
println "Drawing $value at ($x,$y)"
g.drawString(value, (float)x, (float)y)
save()
}

/**
* A very simple test function
*
* @param args
*/
static void main(String [] args) {
Drawing d = new Drawing("/Users/simon/test.png", 800,600, 10,0, 20, 10)
d.log = true

Matrix m = new Matrix([
[2,0,0,3],
[5,0,7,2]
])

println "Drawing $m"

/*
d.lines(m[][0], m[][1], m[][2], m[][3])
.color(255,0,0)
.line(5,3,2,4)
*/

d.with {
color(0,255,0)
line(10,0,14,4)
bars([12],[13.5],[1])
text(12,1, "hello")
}
}
}
118 changes: 118 additions & 0 deletions src/main/groovy/graxxia/IntegerStats.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package graxxia;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;

import org.apache.commons.math3.stat.descriptive.SummaryStatistics;

/**
* An efficient method to calculate percentiles of coverage values
* that doesn't require holding them all in memory or sorting them.
* <p>
* It relies on some limitations regarding coverage values:
* <li>They are integers
* <li>We usually know the approximate range, and don't care about it
* above a certain value. For example, we are unlikely to observe
* values above 1000 and those that do are unlikely to affect the
* 50'th percentile.
*
* @author simon.sadedin@mcri.edu.au
*/
public class IntegerStats extends SummaryStatistics {

private static final long serialVersionUID = 1L;

int [] values = null;

int total = 0;

/**
*
* @param maxPercentileValue
*/
public IntegerStats(int maxPercentileValue) {
values = new int[maxPercentileValue];
Arrays.fill(values, 0);
}

public IntegerStats(int maxPercentileValue, InputStream inStream) throws IOException {
values = new int[maxPercentileValue];
BufferedReader r = new BufferedReader(new InputStreamReader(inStream));
String line = null;
while((line = r.readLine()) != null) {
leftShift(line);
}
}

void leftShift(Object obj) {
if(obj instanceof Integer) {
addValue((Integer)obj);
}
else
if(obj instanceof String) {
addValue(Integer.parseInt(String.valueOf(obj).trim()));
}
else
if(obj instanceof Number) {
addValue(((Number)obj).intValue());
}
}

/**
* Count the given coverage value in calculating the median
* @param coverage
*/
void addValue(int coverage) {
if(coverage>=values.length)
++values[values.length-1];
else
++values[coverage];

super.addValue(coverage);
++total;
}

/**
* Return the specified percentile from the observed coverage counts
* eg: for median, getPercentile(50).
*
* @return the specified percentile, if it is smaller than the max value passed in the
* constructor.
*/
int getPercentile(int percentile) {
int observationsPassed = 0;
int lowerValue = -1;
final int medianIndex = total / (100/percentile);
for(int i=0; i<values.length; ++i) {
observationsPassed += values[i];
if(observationsPassed >= medianIndex) {
if(total%2 == 0) {
// Find the next value and return average of this one and that
lowerValue = i;
for(int k=i+1; k<values.length; ++k) {
if(values[k]>0) {
return (lowerValue + k) / 2;
}
}
}
else
return i;
}
}
return -1;
}

public int getMedian() {
return getPercentile(50);
}

public int getAt(int percentile) {
return getPercentile(percentile);
}

public String toString() {
return super.toString() + "Median: " + getMedian() + "\n";
}
}
25 changes: 25 additions & 0 deletions src/main/groovy/graxxia/IterationDelegate.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Graxxia - Groovy Maths Utililities
*
* Copyright (C) 2014 Simon Sadedin, ssadedin<at>gmail.com and contributors.
*
* This file is licensed under the Apache Software License Version 2.0.
* For the avoidance of doubt, it may be alternatively licensed under GPLv2.0
* and GPLv3.0. Please see LICENSE.txt in your distribution directory for
* further details.
*/
package graxxia
class IterationDelegate {

Integer row = 0

Matrix host

IterationDelegate(Matrix host) {
this.host = host
}

def propertyMissing(String name) {
host[name][row]
}
}
Loading

0 comments on commit 90d80a1

Please sign in to comment.