/* * TransposeRank2DataSet.java * * Created on December 11, 2007, 10:19 PM * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package org.das2.qds.util; import java.util.Arrays; import org.das2.qds.AbstractDataSet; import org.das2.qds.DataSetUtil; import org.das2.qds.QDataSet; /** * wrap a qube dataset to transpose the indeces. This brute force implementation * calculates the index mapping and is implemented without copying. For rank 4 * datasets, order[0] must equal 0. * * @author jbf */ public class TransposeRankNDataSet extends AbstractDataSet { QDataSet source; int[] order; int[] qube; final int shuffleType; private static final int SHUFFLE_123= 0; //brute force, good luck with rank 4. private static final int SHUFFLE_132= 1; private static final int SHUFFLE_213= 2; private static final int SHUFFLE_231= 3; private static final int SHUFFLE_312= 4; private static final int SHUFFLE_321= 5; public TransposeRankNDataSet( QDataSet source, int[] order ) { this.source= source; this.order= new int[order.length]; System.arraycopy( order, 0, this.order, 0, order.length ); this.qube= DataSetUtil.qubeDims(source); for ( int i=0; i<source.rank(); i++ ) { QDataSet depi= (QDataSet) source.property( "DEPEND_"+order[i] ); if ( depi!=null ) properties.put( "DEPEND_"+i, depi ); } int[] lorder= order; if ( order.length==4 ) { if ( order[0]!=0 ) { throw new IllegalArgumentException("rank not supported unless order[0]=0"); } lorder= Arrays.copyOfRange( order, 1, 4 ); for ( int i=0; i<lorder.length; i++ ) { lorder[i]-= 1; } } switch (lorder[0]) { case 0: if ( lorder[1]==1 ) { shuffleType= SHUFFLE_123; } else { shuffleType= SHUFFLE_132; } break; case 1: if ( lorder[1]==0 ) { shuffleType= SHUFFLE_213; } else { shuffleType= SHUFFLE_231; } break; default: if ( lorder[1]==0 ) { shuffleType= SHUFFLE_312; } else { shuffleType= SHUFFLE_321; } break; } } @Override public int rank() { return source.rank(); } @Override public double value(int i) { return super.value(i); } @Override public double value(int i0, int i1) { return source.value( i1, i0 ); //TODO: verify this... } @Override public double value(int i1, int i2, int i3) { // see you on dailywtf... switch ( shuffleType ) { case SHUFFLE_123: return source.value( i1, i2, i3); case SHUFFLE_132: return source.value( i1, i3, i2); case SHUFFLE_213: return source.value( i2, i1, i3); case SHUFFLE_231: return source.value( i2, i3, i1); case SHUFFLE_312: return source.value( i3, i1, i2); case SHUFFLE_321: return source.value( i3, i2, i1); default: throw new RuntimeException("implementation error"); } } @Override public double value(int i0, int i1, int i2, int i3) { // first (0th) element must be slice. switch ( shuffleType ) { case SHUFFLE_123: return source.value( i0, i1, i2, i3); case SHUFFLE_132: return source.value( i0, i1, i3, i2); case SHUFFLE_213: return source.value( i0, i2, i1, i3); case SHUFFLE_231: return source.value( i0, i2, i3, i1); case SHUFFLE_312: return source.value( i0, i3, i1, i2); case SHUFFLE_321: return source.value( i0, i3, i2, i1); default: throw new RuntimeException("implementation error"); } } @Override public Object property(String name) { Object v= properties.get(name); //TODO: verify this return ( v==null ) ? source.property(name) : v; } @Override public Object property(String name, int i) { Object v= properties.get(name); //TODO: verify this return ( v==null ) ? source.property(name,i) : v; } @Override public int length() { return qube[order[0]]; } @Override public int length(int i) { return qube[order[1]]; } @Override public int length( int i, int j ) { return qube[order[2]]; } @Override public int length( int i, int j, int k ) { return qube[order[3]]; } }