/* * Copyright 2004-2010 Information & Software Engineering Group (188/1) * Institute of Software Technology and Interactive Systems * Vienna University of Technology, Austria * * 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.ifs.tuwien.ac.at/dm/somtoolbox/license.html * * 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 at.tuwien.ifs.somtoolbox.apps.viewer; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.image.BufferedImage; import cern.colt.matrix.DoubleMatrix1D; import at.tuwien.ifs.somtoolbox.data.DataDimensionException; /** * Creates a visualization of Rhythm Pattern feature vectors. * * @author Thomas Lidy * @version $Id: RhythmPattern.java 3589 2010-05-21 10:42:01Z mayer $ */ public class RhythmPattern { private int xdim = 0; // matrix dimensions private int ydim = 0; private double[][] mat; // the vector in matrix form private double minv = 0; // min. value of matrix private double maxv = 0; // max. value of matrix private static final int DEFAULT_bx = 5; // default graphics block size in pixel (x) private static final int DEFAULT_by = 5; // default graphics block size in pixel (y) public int bx = DEFAULT_bx; // graphics block size in pixel (x) public int by = DEFAULT_by; // graphics block size in pixel (y) private Color[] palette; /** * This constructor uses pre-defined hard-coded values; it is not recommended to use this constructor it is intended * for backward compatibility for RP feature vector files without the $DATA_TYPE header */ public RhythmPattern(double[] vec) throws DataDimensionException { this(vec, 60, 24); } /** * this constructor uses default graphics block size * * @param vec feature vector given as double[] array (as used for weight vectors) * @param xdim the RP matrix dimension (x) * @param ydim the RP matrix dimension (y) */ public RhythmPattern(double[] vec, int xdim, int ydim) throws DataDimensionException { this(vec, xdim, ydim, DEFAULT_bx, DEFAULT_by); } /** * @param vec feature vector given as double[] array (as used for weight vectors) * @param xdim the RP matrix dimension (x) * @param ydim the RP matrix dimension (y) * @param blocksize_x the blocksize for a RP graphics data point (x) * @param blocksize_y the blocksize for a RP graphics data point (y) */ public RhythmPattern(double[] vec, int xdim, int ydim, int blocksize_x, int blocksize_y) throws DataDimensionException { this.xdim = xdim; this.ydim = ydim; this.bx = blocksize_x; this.by = blocksize_y; if (xdim * ydim != vec.length) { throw new DataDimensionException("Dimensions " + ydim + "x" + xdim + " in Rhythm Pattern do not agree with vector size " + vec.length + "!"); } int ind; minv = Double.POSITIVE_INFINITY; maxv = Double.NEGATIVE_INFINITY; mat = new double[xdim][ydim]; for (int i = 0; i < xdim; i++) { for (int j = 0; j < ydim; j++) { ind = i * ydim + j; mat[i][j] = vec[ind]; if (vec[ind] < minv) { minv = vec[ind]; // determine minimum value } if (vec[ind] > maxv) { maxv = vec[ind]; // determine maximum value } } } initPaint(); } /** * This constructor uses pre-defined hard-coded values; it is not recommended to use this constructor it is intended * for backward compatibility for RP feature vector files without the $DATA_TYPE header */ public RhythmPattern(DoubleMatrix1D vec) throws DataDimensionException { this(vec, 60, 24); } /** constructor with feature vector given as DoubleMatrix1D (as provided by class SOMLibSparseInputData) */ public RhythmPattern(DoubleMatrix1D vec, int xdim, int ydim) throws DataDimensionException { this(vec, xdim, ydim, DEFAULT_bx, DEFAULT_by); } /** * @param vec feature vector given as DoubleMatrix1D (as provided by class SOMLibSparseInputData) * @param xdim the RP matrix dimension (x) * @param ydim the RP matrix dimension (y) * @param blocksize_x the blocksize for a RP graphics data point (x) * @param blocksize_y the blocksize for a RP graphics data point (y) */ public RhythmPattern(DoubleMatrix1D vec, int xdim, int ydim, int blocksize_x, int blocksize_y) throws DataDimensionException { this.xdim = xdim; this.ydim = ydim; this.bx = blocksize_x; this.by = blocksize_y; if (xdim * ydim != vec.size()) { throw new DataDimensionException("Dimensions " + ydim + "x" + xdim + " in Rhythm Pattern do not agree with vector size " + vec.size() + "!"); } // vec.toArray(); DoubleMatrix1D vecsorted = vec.viewSorted(); minv = vecsorted.get(0); maxv = vecsorted.get(vec.size() - 1); // System.out.println("min: " + Double.toString(minv)); // System.out.println("max: " + Double.toString(maxv)); mat = new double[xdim][ydim]; for (int i = 0; i < xdim; i++) { mat[i] = vec.viewPart(ydim * i, ydim).toArray(); // read 24 bands for 1 mod.freq en bloc } initPaint(); } private void initPaint() { palette = initMatlabPalette(); } /** * @return x dimension of RP matrix */ public int getXdim() { return xdim; } /** * @return y dimension of RP matrix */ public int getYdim() { return ydim; } /** * @return size of RhythmPattern in pixels */ public Dimension getSize() { return new Dimension(xdim * bx, ydim * by); } /** * @return RP matrix as double[][] array */ public double[][] getMatrix() { return mat; } /** * @return a RhythmPattern as a BufferedImage */ public BufferedImage getImage() { BufferedImage img = new BufferedImage(xdim * bx, ydim * by, BufferedImage.TYPE_INT_RGB); paint(img.createGraphics()); return img; } /** * paints on Graphics object provided (either by local method or by a Dialog window) */ public void paint(Graphics g) { int xpos, ypos; int colind; int paldim = palette.length - 1; if (maxv == 0.0) { return; // would cause div/0 //TODO throw exception } xpos = 0; ypos = (ydim - 1) * by; for (int j = 0; j < ydim; j++) { for (int i = 0; i < xdim; i++) { // System.out.print(mat[i][j] + " "); colind = (int) ((mat[i][j] - minv) / maxv * paldim); g.setColor(palette[colind]); g.fillRect(xpos, ypos, bx, by); xpos += bx; } // System.out.println(); ypos -= by; xpos = 0; } } /** * this palette is the MATLAB jet colormap it consists of 6 fixed color values which are interpolated through 64 * values */ private Color[] initMatlabPalette() { int i, r, g, b; Color[] palette = new Color[64]; for (i = 0; i < 8; i++) { palette[i] = new Color(0, 0, 143 + i * 16); } g = 0; for (i = 8; i < 23; i++) { g = g + 16; palette[i] = new Color(0, g, 255); } r = 0; b = 255; for (i = 23; i < 39; i++) { palette[i] = new Color(r, 255, b); r = r + 16; b = b - 16; } g = 255; for (i = 39; i < 55; i++) { palette[i] = new Color(255, g, 0); g = g - 16; } r = 255; for (i = 55; i < 63; i++) { palette[i] = new Color(r, 0, 0); r = r - 16; } palette[63] = new Color(128, 0, 0); return palette; } }