NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.
To learn about what's going on, see About the Archive Site.
Hi Andrew, > I've been wanting to get some data like (n)->(lat, lon, name) onto the > screen, but I'm having trouble. > > I've observed that I can write a program with: > > 1. RealType->RealType it does work. > 2. RealType->(RealType, RealType) it does not work! > 3. RealType->(TextType, RealType) it does work. > > In all these cases the domain type is mapped to Display.XAxis and one > of the range types is mapped to Display.Text > > Attached is my program that implements number 2 above, I would > appreciate > help getting this to work. > > The output looks like: > java.lang.ClassCastException: visad.Tuple > at visad.FieldImpl.getRangeCoordinateSystem(FieldImpl.java, > Compiled Code) > ... Congrats, you've found a bug in VisAD. The first one in a long time. Tuple.java shouldn't let you construct a Tuple whose components are all Reals - it should tell you to construct a RealTuple instead. I've attached the fixed version of Tuple.java, which will be in the ftp source distribution the next time I run the tests. In your simple.java, replace: Data[] data = { new Real(RealType.Latitude, 33.5), new Real(RealType.Longitude, 33.5), new Real(cnameType, 33.5) }; Tuple rangeTuple = new Tuple(rangeTupleType, data); with: Real[] data = { new Real(RealType.Latitude, 33.5), new Real(RealType.Longitude, 33.5), new Real(cnameType, 33.5) }; RealTuple rangeTuple = new RealTuple(data); Thanks for finding this. Cheers, Bill ---------------------------------------------------------- Bill Hibbard, SSEC, 1225 W. Dayton St., Madison, WI 53706 hibbard@xxxxxxxxxxxxxxxxx 608-263-4427 fax: 608-263-6738 http://www.ssec.wisc.edu/~billh/vis.html
// // Tuple.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2000 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; import java.rmi.*; import java.util.Vector; /** Tuple is the general VisAD data class for vectors. Tuple objects are immutable.<P> */ public class Tuple extends DataImpl implements TupleIface { Data[] tupleComponents; /** construct a Tuple object with missing value */ public Tuple(TupleType type) { super(type); if (type instanceof RealTupleType && !(this instanceof RealTuple)) { throw new VisADError("must construct as RealTupleType"); } } /** construct a Tuple object from a type and an array of Data objects */ public Tuple(TupleType type, Data[] datums) throws VisADException, RemoteException { this(type, datums, true); } /** construct a Tuple object from a type and an array of Data objects */ public Tuple(TupleType type, Data[] datums, boolean copy) throws VisADException, RemoteException { super(type); if (!checkTupleType(type, datums)) { throw new TypeException("Tuple: type does not match data"); } if (type instanceof RealTupleType && !(this instanceof RealTuple)) { throw new TypeException("must construct as RealTupleType"); } int n = datums.length; tupleComponents = new Data[n]; for (int i=0; i<n; i++) { if (copy) { tupleComponents[i] = (Data) datums[i].dataClone(); } else { tupleComponents[i] = datums[i]; } if (tupleComponents[i] instanceof DataImpl) { ((DataImpl) tupleComponents[i]).setParent(this); } } } /** construct a Tuple object from an array of Data objects; this constructs its MathType from the MathTypes of the data array; only copy data if copy == true */ public Tuple(Data[] datums, boolean copy) throws VisADException, RemoteException { this(buildTupleType(datums), datums, copy); } /** construct a Tuple object from an array of Data objects; this constructs its MathType from the MathTypes of the data array; components are copies of data */ public Tuple(Data[] datums) throws VisADException, RemoteException { this(buildTupleType(datums), datums, true); } public static Tuple makeTuple(Data[] datums) throws VisADException, RemoteException { return new Tuple(datums); } /** check a TupleType for an array of Data */ static boolean checkTupleType(TupleType type, Data[] datums) throws VisADException, RemoteException { if (datums == null || type == null) return false; int n = datums.length; if (n != type.getDimension()) return false; for (int i=0; i<n; i++) { if (!type.getComponent(i).equals(datums[i].getType())) return false; } return true; } /** make a TupleType for an array of Data */ public static TupleType buildTupleType(Data[] datums) throws VisADException, RemoteException { if (datums == null) { throw new TypeException("Tuple: # components must be > 0"); } int n = datums.length; if (n < 1) { throw new TypeException("Tuple: # components must be > 0"); } MathType[] types = new MathType[n]; boolean allReal = true; for (int i=0; i<n; i++) { types[i] = datums[i].getType(); if (!(types[i] instanceof RealType)) allReal = false; } if (allReal) { RealType[] real_types = new RealType[n]; for (int i=0; i<n; i++) real_types[i] = (RealType) types[i]; return new RealTupleType(real_types); } else { return new TupleType(types); } } public Real[] getRealComponents() throws VisADException, RemoteException { if (tupleComponents == null) return null; Vector reals = new Vector(); for (int i=0; i<tupleComponents.length; i++) { if (tupleComponents[i] instanceof Real) { reals.addElement(tupleComponents[i]); } else if (tupleComponents[i] instanceof RealTuple) { RealTuple rt = (RealTuple) tupleComponents[i]; for (int j=0; j<rt.getDimension(); j++) { reals.addElement(rt.getComponent(j)); } } } if (reals.size() == 0) return null; Real[] realComponents = new Real[reals.size()]; for (int i=0; i<reals.size(); i++) { realComponents[i] = (Real) reals.elementAt(i); } return realComponents; } /** return array of components */ public Data[] getComponents() { return tupleComponents; } /** return number of components */ public int getDimension() { if (tupleComponents != null) { return tupleComponents.length; } else { return ((TupleType) getType()).getDimension(); } } /** return component for i between 0 and getDimension() - 1 */ public Data getComponent(int i) throws VisADException, RemoteException { if (isMissing()) { return ((TupleType) Type).getComponent(i).missingData(); } else if (0 <= i && i < tupleComponents.length) { return (Data) tupleComponents[i]; } else { throw new TypeException("Tuple: component index out of range"); } } public boolean isMissing() { return (tupleComponents == null); } /*- TDR May 1998 public Data binary(Data data, int op, int sampling_mode, int error_mode) throws VisADException, RemoteException { */ public Data binary(Data data, int op, MathType new_type, int sampling_mode, int error_mode ) throws VisADException, RemoteException { /* BINARY - TDR May 28, 1998 */ if ( new_type == null ) { throw new TypeException("binary: new_type may not be null" ); } MathType m_type; /* BINARY - end */ if (data instanceof RealTuple) { throw new TypeException("Tuple.binary: types don't match"); } else if (data instanceof Tuple) { if (!Type.equalsExceptName(data.getType())) { throw new TypeException("Tuple.binary: types don't match"); } /* BINARY - TDR May 28, 1998 */ if ( !Type.equalsExceptName(new_type) ) { throw new TypeException(); } /* BINARY - end */ if (isMissing() || data.isMissing()) { return new Tuple((TupleType) new_type); } Data[] datums = new Data[tupleComponents.length]; for (int j=0; j<tupleComponents.length; j++) { /* BINARY - TDR June 2, 1998 */ m_type = ((TupleType)new_type).getComponent(j); /* end */ datums[j] = tupleComponents[j].binary(((Tuple) data).getComponent(j), op, m_type, sampling_mode, error_mode); } return new Tuple(datums); } else if (data instanceof Real) { /* BINARY - TDR May 28, 1998 */ if ( !Type.equalsExceptName(new_type) ) { throw new TypeException(); } /* BINARY - end */ if (isMissing() || data.isMissing()) { return new Tuple((TupleType) new_type); } Data[] datums = new Data[tupleComponents.length]; for (int j=0; j<tupleComponents.length; j++) { /* BINARY - TDR June 2, 1998 */ m_type = ((TupleType)new_type).getComponent(j); /* end */ datums[j] = tupleComponents[j].binary(data, op, m_type, sampling_mode, error_mode); } return new Tuple(datums); } else if (data instanceof Text) { throw new TypeException("Tuple.binary: types don't match"); } else if (data instanceof Field) { /* BINARY - TDR May 28, 1998 return data.binary(this, invertOp(op), sampling_mode, error_mode); */ /* BINARY - TDR June 3, 1998 */ if ( !(data.getType()).equalsExceptName(new_type) ) { throw new TypeException(); } return data.binary(this, invertOp(op), new_type, sampling_mode, error_mode); /* BINARY - end */ } else { throw new TypeException("Tuple.binary"); } } /*- TDR July 1998 public Data unary(int op, int sampling_mode, int error_mode) throws VisADException, RemoteException { */ public Data unary(int op, MathType new_type, int sampling_mode, int error_mode) throws VisADException, RemoteException { if ( new_type == null ) { throw new TypeException("unary: new_type may not be null"); } if ( !Type.equalsExceptName( new_type )) { throw new TypeException("unary: new_type doesn't match return type"); } TupleType T_type = (TupleType)new_type; if (isMissing()) return new Tuple((TupleType) new_type); Data[] datums = new Data[tupleComponents.length]; for (int j=0; j<tupleComponents.length; j++) { datums[j] = tupleComponents[j].unary(op, T_type.getComponent(j), sampling_mode, error_mode); } return new Tuple(datums); } public DataShadow computeRanges(ShadowType type, DataShadow shadow) throws VisADException, RemoteException { if (isMissing()) return shadow; for (int i=0; i<tupleComponents.length; i++) { shadow = tupleComponents[i].computeRanges(((ShadowTupleType) type).getComponent(i), shadow); } return shadow; } /** return a Tuple that clones this, except its ErrorEstimate-s are adjusted for sampling errors in error */ public Data adjustSamplingError(Data error, int error_mode) throws VisADException, RemoteException { if (isMissing() || error == null || error.isMissing()) return this; int n = tupleComponents.length; Data[] newComponents = new Data[n]; for (int i=0; i<n; i++) { Data errorComponent = ((Tuple) error).getComponent(i); newComponents[i] = tupleComponents[i].adjustSamplingError(errorComponent, error_mode); } return new Tuple(newComponents); } /** * A wrapper around {@link #getComponent(int) getComponent} for JPython. * * @return The requested Data object. */ public Data __getitem__(int index) throws VisADException, RemoteException { return getComponent(index); } /** * A wrapper around {@link #getDimension() getDimension} for JPython. * * @return Number of components. */ public int getLength() { return getDimension(); } public Object clone() { Tuple tuple; try { if (tupleComponents == null) { tuple = new Tuple((TupleType )getType()); } else { int n = tupleComponents.length; Data[] datums = new Data[n]; for (int i=0; i<n; i++) { datums[i] = (Data) tupleComponents[i].dataClone(); } tuple = new Tuple(datums); } } catch (VisADException e) { throw new VisADError("Tuple.clone: VisADException occurred"); } catch (RemoteException e) { throw new VisADError("Tuple.clone: RemoteException occurred"); } return tuple; } public String longString(String pre) throws VisADException, RemoteException { String s = pre + "Tuple\n" + pre + " Type: " + Type.toString() + "\n"; if (isMissing()) return s + " missing\n"; for (int i=0; i<tupleComponents.length; i++) { s = s + pre + " Tuple Component " + i + ":\n" + tupleComponents[i].longString(pre + " "); } return s; } /** * Indicates if this Tuple is identical to another object. * @param obj The other object. * @return <code>true</code> if and only if the other object is * a Tuple and both Tuple-s have identical component * sequences. */ public boolean equals(Object obj) { boolean equals; if (!(obj instanceof Tuple)) { equals = false; } else { Tuple that = (Tuple)obj; if (this == that) { equals = true; } else if (tupleComponents == null || that.tupleComponents == null) { equals = tupleComponents == that.tupleComponents; } else if (tupleComponents.length != that.tupleComponents.length) { equals = false; } else { equals = true; for (int i = 0; i < tupleComponents.length; ++i) if (!(tupleComponents[i].equals(that.tupleComponents[i]))) { equals = false; break; } } } return equals; } /** * Returns the hash code of this object. * @return The hash code of this object. */ public int hashCode() { int hashCode = 0; if (tupleComponents != null) for (int i = 0; i < tupleComponents.length; ++i) hashCode ^= tupleComponents[i].hashCode(); return hashCode; } }
visad
archives: