/* * BundleDataSet.java * * Copied from JoinDataSet in June 2009 * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package org.das2.qds; import java.util.ArrayList; import java.util.List; /** * create a high rank dataset the last dimension being the bundle. Each * dataset must have the same length. * * Modification History: * 2015-10-30: copied from BundleDataSet * See https://sourceforge.net/p/autoplot/feature-requests/267/ * @author jbf */ public final class TailBundleDataSet extends AbstractDataSet { List datasets; /** * rank of the dataset. */ int rank; /** * dimensions of each dataset. */ int[] qube; /** Creates a new instance of BundleDataSet with the given rank. Rank 1 * datasets can bundle rank 0 datasets, while rank 2 can only bundle * rank 1 datasets with the same depend_0. * @param rank rank of the bundle. */ public TailBundleDataSet( int rank ) { this.rank= rank; datasets= new ArrayList(); if ( rank==4 ) { putProperty( QDataSet.BUNDLE_3, new BundleDescriptor() ); putProperty( QDataSet.QUBE, Boolean.TRUE ); } else if ( rank==3 ) { putProperty( QDataSet.BUNDLE_2, new BundleDescriptor() ); putProperty( QDataSet.QUBE, Boolean.TRUE ); } else if ( rank==2 ) { putProperty( QDataSet.BUNDLE_1, new BundleDescriptor() ); putProperty( QDataSet.QUBE, Boolean.TRUE ); } else { putProperty( QDataSet.BUNDLE_0, new BundleDescriptor() ); } } /** * create a bundle with the first dataset. The result will have * rank N+1 where ds has rank N. * @param ds rank N dataset. */ public TailBundleDataSet( QDataSet ds ) { this( ds.rank()+1 ); bundle(ds); } /** * add the dataset to the bundle of datasets. Currently this implementation only supports rank N-1 datasets (N is this * dataset's rank), but the QDataSet spec allows for qube datasets of any rank>1 to be bundled. This limitation will be removed * in a future version. (Note QDataSet changes http://autoplot.org/QDataSet#2011-Apr-13) * * @param ds */ public void bundle( QDataSet ds ) { if ( ds.rank()!=this.rank-1 ) { throw new IllegalArgumentException("dataset rank must be "+(this.rank-1)); } if ( this.rank>1 ) { if ( this.qube!=null ) { int[] qube= DataSetUtil.qubeDims(ds); if ( qube[0]!=this.qube[0] ) { throw new IllegalArgumentException( String.format( "dataset length (%d) is not consistent with the bundle's length (%d)", ds.length(), this.qube[0]) ); } } else { this.qube= DataSetUtil.qubeDims(ds); } } datasets.add( ds ); } /** * allow to simply unbundle the dataset. * @param i the index. * @return the dataset at i. */ public QDataSet unbundle(int i) { return datasets.get(i); } /** * special dataset describing the bundled datasets in a BundleDataSet. */ public class BundleDescriptor extends AbstractDataSet { @Override public int rank() { return 2; } @Override public int length() { return datasets.size(); } @Override public int length(int i) { return 0; // support bundling just rank N-1 datasets. } @Override public Object property(String name, int i) { Object v= properties.get( name+"__"+i ); if ( i>=datasets.size() ) { throw new IndexOutOfBoundsException("No dataset at index " + i + " only " + datasets.size() +" datasets." ); } if ( v==null ) { if ( DataSetUtil.isInheritedProperty(name) ) { // UNITS, LABEL, TITLE, etc. return datasets.get(i).property(name); } else { // the property DEPENDNAME_0 should be used in a bundle descriptor. This property should not // be here, because we must be able to transfer BUNDLE_1 to BUNDLE_0. return null; } } else { return v; } } @Override public double value(int i0, int i1) { // support bundling just rank N-1 datasets. to support higher rank // datasets, this should return the qube dims. throw new IndexOutOfBoundsException("length=0"); } @Override public String toString() { StringBuilder names= new StringBuilder(); String s= (String) datasets.get(0).property(QDataSet.NAME); names.append( s==null ? "data" : s ); for ( int i=1; i