//
// HdfeosDomain.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad.data.hdfeos;
import visad.Set;
import visad.MathType;
import visad.RealType;
import visad.GriddedSet;
import visad.Gridded1DSet;
import visad.IntegerNDSet;
import visad.LinearNDSet;
import visad.SampledSet;
import visad.ProductSet;
import visad.SetException;
import visad.VisADException;
import visad.RealTupleType;
import visad.CoordinateSystem;
import visad.GridCoordinateSystem;
import visad.Unit;
class HdfeosDomain
{
private EosStruct struct;
final static int INTEGER = 0;
final static int HYBRID = 1; // product of next two
final static int FACTORED = 2; // aligned with R^N
final static int FACTORED_ARITH = 3; //
final static int UNFACTORED = 4; // non-aligned with R^N
final static int LINEAR = 5;
final static int SINGLE = 6;
private int op;
private NamedDimension[] domDims;
private DimensionSet domDimSet = null;
private Variable[] domVars;
private int domainDim;
private int manifoldDim;
private int[] lengths = null;
private int[] inv_lengths = null;
private int[] num_type = null;
private Calibration[] cal = null;
private int n_samples;
private float[][] samples;
private String[] name_s = null;
MathType mathtype = null;
private CoordinateSystem coord_sys = null;
private Unit[] units = null;
private Set domainSet = null;
private HdfeosDomain gridCoordSys = null;
private boolean subRank;
private int[] start = null;
private int[] edge = null;
private int[] stride = null;
public HdfeosDomain( EosStruct struct,
DimensionSet dimSet)
throws VisADException
{
this(struct, dimSet.getElements(), null, null);
}
public HdfeosDomain( EosStruct struct,
DimensionSet dimSet,
CoordinateSystem coord_sys )
throws VisADException
{
this(struct, dimSet.getElements(), coord_sys, null);
}
public HdfeosDomain( EosStruct struct,
DimensionSet dimSet,
CoordinateSystem coord_sys,
Unit[] units )
throws VisADException
{
this(struct, dimSet.getElements(), coord_sys, units);
}
public HdfeosDomain( EosStruct struct,
NamedDimension dim )
throws VisADException
{
NamedDimension[] dims = {dim};
initializeNoVars( struct, dims );
}
public HdfeosDomain( EosStruct struct,
NamedDimension[] dims,
CoordinateSystem coord_sys,
Unit[] units)
throws VisADException
{
this.coord_sys = coord_sys;
this.units = units;
initializeNoVars( struct, dims );
}
public HdfeosDomain( EosStruct struct,
DimensionSet dimSet,
HdfeosDomain gridCoordSys )
throws VisADException
{
this.coord_sys = getNullGridCoordinateSystem(gridCoordSys);
this.gridCoordSys = gridCoordSys;
initializeNoVars( struct, dimSet.getElements() );
}
public static GridCoordinateSystem
getNullGridCoordinateSystem( HdfeosDomain gridCoordSys )
throws VisADException
{
RealTupleType reference = (RealTupleType)gridCoordSys.getType();
int dim = reference.getDimension();
int[] lens = new int[dim];
for ( int ii = 0; ii < dim; ii++ ) {
lens[ii] = 2;
}
IntegerNDSet set = new IntegerNDSet(reference, lens);
GridCoordinateSystem c_sys = new GridCoordinateSystem(set);
return c_sys;
}
private void initializeNoVars( EosStruct struct,
NamedDimension[] dims)
throws VisADException
{
this.struct = struct;
domDims = dims;
domainDim = dims.length;
lengths = new int[ domainDim ];
inv_lengths = new int[ domainDim ];
manifoldDim = domainDim;
name_s = new String[ domainDim ];
this.domDimSet = new DimensionSet(dims);
if ( units == null ) {
units = new Unit[domainDim];
}
start = new int[ manifoldDim ];
stride = new int[ manifoldDim ];
edge = new int[ manifoldDim ];
n_samples = 1;
for ( int ii = 0; ii < domainDim; ii++ )
{
name_s[ii] = domDims[ii].getName();
lengths[ii] = domDims[ii].getLength();
n_samples *= lengths[ii];
start[ii] = 0;
edge[ii] = lengths[ii];
stride[ii] = 1;
}
for ( int kk = 0; kk < domainDim; kk++ )
{
inv_lengths[kk] = lengths[(domainDim-1)-kk];
}
op = LINEAR;
subRank = false;
mathtype = makeType(null);
}
public HdfeosDomain( EosStruct struct,
Variable[] vars,
NamedDimension[] dims )
throws VisADException
{
initialize( struct, vars, dims );
}
public HdfeosDomain( EosStruct struct,
VariableSet v_set,
DimensionSet d_set )
throws VisADException
{
domDimSet = d_set;
initialize(struct, v_set.getElements(), d_set.getElements());
}
public HdfeosDomain( EosStruct struct,
Variable var )
throws VisADException
{
Variable[] vars = new Variable[1];
NamedDimension[] dims = new NamedDimension[1];
vars[0] = var;
dims[0] = var.getDim(0);
initialize(struct, vars, dims);
}
private void initialize( EosStruct struct,
Variable[] vars,
NamedDimension[] dims )
throws VisADException
{
this.struct = struct;
domVars = vars;
int n_vars = vars.length;
this.num_type = new int[n_vars];
this.cal = new Calibration[n_vars];
domDims = dims;
int n_dims = dims.length;
boolean all_1D = false;
boolean one_1D = false;
boolean all_eq = true;
domainDim = vars.length;
manifoldDim = dims.length;
if ( domDimSet == null ) {
domDimSet = new DimensionSet( dims );
}
name_s = new String[ domainDim ];
if ( units == null ) {
units = new Unit[domainDim];
}
if (domainDim == 1)
{
op = SINGLE;
subRank = false;
start = new int[1];
edge = new int[1];
stride = new int[1];
name_s[0] = domVars[0].getName();
num_type[0] = domVars[0].getNumberType();
cal[0] = domVars[0].getCalibration();
}
else
{
int v_rank = 1;
int v_rank0 = domVars[0].getRank();
for ( int ii = 0; ii < n_vars; ii++ )
{
v_rank = domVars[ii].getRank();
if ( n_dims != 1 )
{
all_1D = false;
if ( v_rank != v_rank0 )
{
all_eq = false;
}
}
else
{
one_1D = true;
}
name_s[ii] = domVars[ii].getName();
num_type[ii] = domVars[ii].getNumberType();
cal[ii] = domVars[ii].getCalibration();
}
if ( all_1D )
{
op = FACTORED;
subRank = false;
start = new int[1];
edge = new int[1];
stride = new int[1];
}
else if ( all_eq )
{
if ( v_rank > manifoldDim ) {
subRank = true;
}
else if ( v_rank == manifoldDim ) {
subRank = false;
}
else {
throw new HdfeosException("variables rank cannot be greater"+
" than manifoldDim" );
}
op = UNFACTORED;
start = new int[v_rank];
stride = new int[v_rank];
edge = new int[v_rank];
}
else
{
throw new HdfeosException("undefined domain case");
}
}
lengths = new int[ manifoldDim ];
inv_lengths = new int[ manifoldDim];
n_samples = 1;
for ( int ii = 0; ii < manifoldDim; ii++ )
{
lengths[ii] = domDims[ii].getLength();
n_samples *= lengths[ii];
}
for ( int kk = 0; kk < manifoldDim; kk++ )
{
inv_lengths[kk] = lengths[(manifoldDim-1)-kk];
}
samples = new float[domainDim][n_samples];
mathtype = makeType(null);
}
public DimensionSet getDimSet()
{
return domDimSet;
}
MathType makeType(CoordinateSystem coord_sys)
throws VisADException
{
int inv_ii;
RealType[] r_types = new RealType[domainDim];
for ( int ii = 0; ii < domainDim; ii++ ) {
inv_ii = (domainDim-1) - ii;
r_types[ii] = RealType.getRealType(name_s[inv_ii], units[inv_ii], null);
}
if ( r_types.length == 1 ) {
return r_types[0];
}
else {
if ( coord_sys == null ) {
return new RealTupleType(r_types, this.coord_sys, null);
}
else {
return new RealTupleType(r_types, coord_sys, null);
}
}
}
public MathType getType()
throws VisADException
{
return mathtype;
}
public Set getData()
throws VisADException
{
if ( !subRank ) {
return getData(null);
}
else {
throw new HdfeosException("getData(int[] indexes) must be used");
}
}
public Set getData( int[] indexes )
throws VisADException
{
int cnt = 0;
if ( indexes == null )
{
if ( subRank ) {
throw new HdfeosException("indexes cannot be null");
}
else if ( domainSet != null ) {
return domainSet;
}
}
else
{
if ( !subRank ) {
throw new HdfeosException("getData() must be used");
}
for ( int ii = 0; ii < indexes.length; ii++ ) {
start[cnt] = indexes[ii];
edge[cnt] = 1;
cnt++;
}
}
Set set = null;
switch (op)
{
case UNFACTORED:
for ( int kk = 0; kk < domainDim; kk++ )
{
for ( int ii = 0; ii < manifoldDim; ii++ ) {
start[cnt+ii] = 0;
edge[cnt+ii] = lengths[ii];
stride[cnt+ii] = 1;
}
struct.readData(name_s[kk], start, stride, edge,
num_type[kk], cal[kk], samples[kk] );
}
set = GriddedSet.create(mathtype, samples, inv_lengths);
//-set = new GriddedSet(mathtype, samples, inv_lengths);
break;
case SINGLE:
struct.readData(name_s[0], start, stride, edge,
num_type[0], cal[0], samples[0]);
set = new Gridded1DSet(mathtype, samples, lengths[0]);
break;
case LINEAR:
if ( gridCoordSys == null ) {
set = new IntegerNDSet(mathtype, lengths, null, null, null);
}
else {
GriddedSet geo_domain;
try {
geo_domain = (GriddedSet) gridCoordSys.getData(indexes);
}
catch ( SetException e ) {
System.out.println( (gridCoordSys.getType()).toString()+" "
+e.getMessage());
set = new IntegerNDSet(mathtype, lengths, null, null, null);
break;
}
int[] lens = geo_domain.getLengths();
double[] firsts = new double[domainDim];
double[] lasts = new double[domainDim];
for ( int ii = 0; ii < domainDim; ii++ ) {
firsts[ii] = 0;
lasts[ii] = lens[ii];
}
GridCoordinateSystem c_sys = new GridCoordinateSystem(geo_domain);
set = new LinearNDSet(mathtype, firsts, lasts, lengths, c_sys, null, null);
}
break;
case FACTORED:
SampledSet[] sets = new SampledSet[domainDim];
for ( int kk = 0; kk < domainDim; kk++ ) {
start[0] = 0;
edge[0] = lengths[kk];
stride[0] = 1;
struct.readData(name_s[kk], start, stride, edge,
num_type[kk], cal[kk], samples[kk]);
sets[kk] = new Gridded1DSet(mathtype, samples, lengths[kk]);
}
set = new ProductSet(mathtype, sets);
break;
}
if ( !subRank ) {
domainSet = set;
}
return set;
}
public EosStruct getStruct()
{
return struct;
}
}