Exemple #1
0
  /**
   * Indicates if a VisAD MathType is compatible with this instance. A RealType is compatible if its
   * {@link RealType#equalsExceptNameButUnits} method returns true when given the return value of
   * {@link #getRealType()} and if this quantity has no coordinate system transformation. A
   * RealTupleType is compatible if its {@link RealTupleType#equalsExceptNameButUnits} method
   * returns true when given the return value of {@link #getRealTupleType()} and if the coordinate
   * system transformations are compatible. A SetType is compatible if its RealTupleType is
   * compatible. A FunctionType is compatible if the MathType of its range is compatible. All other
   * MathTypes are incompatible.
   *
   * @param type The VisAD MathType to examine for compatibility.
   * @return <code>true</code> if and only if the MathType is compatible with this instance.
   * @throws VisADException VisAD failure.
   */
  public boolean isCompatible(MathType type) throws VisADException {

    boolean isCompatible;

    if (type instanceof RealType) {
      isCompatible =
          ((RealType) type).equalsExceptNameButUnits(realType)
              && (getRealTupleType().getCoordinateSystem() == null);
    } else if (type instanceof RealTupleType) {
      RealTupleType thisTupleType = getRealTupleType();
      RealTupleType thatTupleType = (RealTupleType) type;

      if (!thatTupleType.equalsExceptNameButUnits(thisTupleType)) {
        isCompatible = false;
      } else {
        CoordinateSystem thisCS = thisTupleType.getCoordinateSystem();
        CoordinateSystem thatCS = thatTupleType.getCoordinateSystem();

        isCompatible =
            ((thisCS == null)
                ? thatCS == null
                : thisCS.getReference().equalsExceptNameButUnits(thatCS.getReference()));
      }
    } else if (type instanceof SetType) {
      isCompatible = isCompatible(((SetType) type).getDomain());
    } else if (type instanceof FunctionType) {
      isCompatible = isCompatible(((FunctionType) type).getRange());
    } else {
      isCompatible = false;
    }

    return isCompatible;
  }
Exemple #2
0
  /**
   * Set the sounding in the table
   *
   * @param sounding the sounding
   * @throws RemoteException Java RMI problem
   * @throws VisADException problem dissecting data
   */
  private void setupTable(Field sounding) throws VisADException, RemoteException {

    Set domain = sounding.getDomainSet();
    CoordinateSystem cs = domain.getCoordinateSystem();

    numDomainCols = domain.getDimension();
    if (cs != null) {
      numDomainCols++;
    }
    RealType[] rangeComps = ((FunctionType) sounding.getType()).getRealComponents();
    numRangeCols = rangeComps.length;
    columnNames = new String[numDomainCols + numRangeCols];

    SetType t = (SetType) domain.getType();
    Unit[] units = domain.getSetUnits();
    RealTupleType rtt = t.getDomain();
    RealType[] comps = rtt.getRealComponents();
    columnNames[0] = makeColumnName(comps[0], units[0]);
    if ((cs != null)) {
      RealTupleType refType = cs.getReference();
      RealType[] refComps = refType.getRealComponents();
      Unit[] refUnits = cs.getReferenceUnits();
      columnNames[1] = makeColumnName(refComps[0], refUnits[0]);
    }

    // set for default
    for (int i = 0; i < rangeComps.length; i++) {
      columnNames[numDomainCols + i] =
          makeColumnName(rangeComps[i], rangeComps[i].getDefaultUnit());
    }
    // wind
    if (rangeComps.length > 2) {
      csUnits = new Unit[] {rangeComps[2].getDefaultUnit(), rangeComps[3].getDefaultUnit()};
      haveUV =
          (Unit.canConvert(csUnits[0], CommonUnit.meterPerSecond)
              && Unit.canConvert(csUnits[1], CommonUnit.meterPerSecond));
      if (haveUV) {
        windTransform =
            new InverseCoordinateSystem(
                new RealTupleType(Speed.getRealType(), Direction.getRealType()),
                new PolarHorizontalWind.PolarCoordinateSystem(
                    new RealTupleType(rangeComps[2], rangeComps[3]),
                    CommonUnit.meterPerSecond,
                    CommonUnit.degree));
      } else {
        windTransform = new PolarHorizontalWind.PolarCoordinateSystem(csUnits[0], csUnits[1]);
      }
    }
    if (model == null) {
      model = new SoundingTableModel();
      sorter = new TableSorter(model);
      JTableHeader header = getTableHeader();
      header.setToolTipText("Click to sort");
      sorter.setTableHeader(getTableHeader());
      setModel(sorter);
      setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
      setPreferredScrollableViewportSize(new Dimension(400, 200));
      getTableHeader().setReorderingAllowed(false);
    }
  }
Exemple #3
0
  void setupServerData(LocalDisplay[] dpys) throws RemoteException, VisADException {
    Unit super_degree = CommonUnit.degree.scale(2.5);
    RealType lon = RealType.getRealType("lon", super_degree);

    DataReference ref = loadFile();
    if (ref == null) {
      System.err.println("must specify netCDF file name");
      System.exit(1);
      return;
    }

    FieldImpl netcdf_data = (FieldImpl) ref.getData();

    // compute ScalarMaps from type components
    FunctionType ftype = (FunctionType) netcdf_data.getType();
    RealTupleType dtype = ftype.getDomain();
    MathType rntype = ftype.getRange();
    int n = dtype.getDimension();
    dpys[0].addMap(new ScalarMap((RealType) dtype.getComponent(0), Display.XAxis));
    if (n > 1) {
      dpys[0].addMap(new ScalarMap((RealType) dtype.getComponent(1), Display.YAxis));
    }
    if (n > 2) {
      dpys[0].addMap(new ScalarMap((RealType) dtype.getComponent(2), Display.ZAxis));
    }
    if (rntype instanceof RealType) {
      dpys[0].addMap(new ScalarMap((RealType) rntype, Display.Green));
      if (n <= 2) {
        dpys[0].addMap(new ScalarMap((RealType) rntype, Display.ZAxis));
      }
    } else if (rntype instanceof RealTupleType) {
      int m = ((RealTupleType) rntype).getDimension();
      RealType rr = (RealType) ((RealTupleType) rntype).getComponent(0);
      dpys[0].addMap(new ScalarMap(rr, Display.Green));
      if (n <= 2) {
        if (m > 1) {
          rr = (RealType) ((RealTupleType) rntype).getComponent(1);
        }
        dpys[0].addMap(new ScalarMap(rr, Display.ZAxis));
      }
    }
    dpys[0].addMap(new ConstantMap(0.5, Display.Red));
    dpys[0].addMap(new ConstantMap(0.0, Display.Blue));

    dpys[0].addReference(ref, null);

    System.out.println("now saving data as 'save.nc' and re-reading");

    Plain plain = new Plain();
    try {
      plain.save("save.nc", netcdf_data, true);
      netcdf_data = (FieldImpl) plain.open("save.nc");
    } catch (IOException e) {
      System.err.println("Couldn't open \"save.nc\": " + e.getMessage());
      System.exit(1);
      return;
    }
  }
Exemple #4
0
  /**
   * Set the sounding in the table
   *
   * @param sounding the sounding
   * @throws RemoteException Java RMI problem
   * @throws VisADException problem dissecting data
   */
  private void setSounding(Field sounding) throws VisADException, RemoteException {
    domainData = null;

    // domain values
    Set domain = sounding.getDomainSet();
    CoordinateSystem cs = domain.getCoordinateSystem();

    float[][] domSamples = domain.getSamples(false);
    if ((cs != null)) {
      float[][] domFloats = Set.copyFloats(domSamples);
      // Must convert from the default coordinate domain system to
      // the domain coordinate system of the sounding.
      String fromUnit = sounding.getDomainUnits()[0].toString();
      String toUnit = cs.getCoordinateSystemUnits()[0].toString();
      if (!fromUnit.equals(toUnit) && SimpleUnit.isCompatible(fromUnit, toUnit)) {
        float conversionFactor = (float) SimpleUnit.getConversionFactor(fromUnit, toUnit);
        for (int i = 0; i < domFloats.length; i++) {
          for (int j = 0; j < domFloats[i].length; j++) {
            domFloats[i][j] = domFloats[i][j] * conversionFactor;
          }
        }
      }
      float[][] refData = cs.toReference(domFloats);
      domainData = new float[][] {domSamples[0], refData[0]};
    }
    // range values
    RealType[] rangeComps = ((FunctionType) sounding.getType()).getRealComponents();
    rangeData = sounding.getFloats(false);

    // wind
    if (rangeComps.length > 2) {
      transformWinds = (showUAndV && !haveUV) || (!showUAndV && haveUV);
      if (!transformWinds) {
        for (int i = 2; i < 4; i++) {
          columnNames[numDomainCols + i] =
              makeColumnName(rangeComps[i], rangeComps[i].getDefaultUnit());
        }
      } else {
        RealTupleType refType = windTransform.getReference();
        Unit[] refUnits = windTransform.getReferenceUnits();
        for (int i = 0; i < 2; i++) {
          columnNames[numDomainCols + i + 2] =
              makeColumnName((RealType) refType.getComponent(i), refUnits[i]);
        }
        float[][] newVals =
            windTransform.toReference(Set.copyFloats(new float[][] {rangeData[2], rangeData[3]}));
        rangeData[2] = newVals[0];
        rangeData[3] = newVals[1];
      }
    }
    sorter.setTableModel(model);
  }
  /**
   * creates the ScalarMaps for color for this Displayable.
   *
   * @throws VisADException VisAD failure.
   * @throws RemoteException Java RMI failure.
   */
  private void setColorMaps() throws RemoteException, VisADException {

    ScalarMapSet set = new ScalarMapSet();
    for (int i = 0; i < colorMaps.length; i++) {
      colorMaps[i] = new ScalarMap((RealType) colorTupleType.getComponent(i), mapType);
      /* TODO: maybe allow user to set range.  If so, just copy
      logic from RGBDisplayable */
      // -TDR colorMaps[i].setRange(0, 255);
      set.add(colorMaps[i]);
      final int colorMapIndex = i;
      colorMaps[i].addScalarMapListener(
          new ScalarMapListener() {
            public void controlChanged(ScalarMapControlEvent event)
                throws RemoteException, VisADException {
              int id = event.getId();
              if ((id == ScalarMapEvent.CONTROL_ADDED) || (id == ScalarMapEvent.CONTROL_REPLACED)) {
                setColorsInControls(colorPalette, colorMapIndex);
              }
            }

            public void mapChanged(ScalarMapEvent event) throws RemoteException, VisADException {}
          });
    }

    setScalarMapSet(set);
    setColorsInControls(colorPalette);
  }
 /**
  * Return <CODE>true</CODE> if <CODE>type</CODE> is legal for this <CODE>DisplayRenderer</CODE>;
  * for example, 2-D <CODE>DisplayRenderer</CODE>s use this to disallow mappings to <I>ZAxis</I>
  * and <I>Latitude</I>.
  *
  * @param type The mapping type to check.
  * @return <CODE>true</CODE> if <CODE>type</CODE> is legal.
  */
 public boolean legalDisplayScalar(DisplayRealType type) {
   // First check to see if it is a member of the default list
   for (int i = 0; i < Display.DisplayRealArray.length; i++) {
     if (Display.DisplayRealArray[i].equals(type)) return true;
   }
   // if we get here, it's not one of the defaults.  See if it has
   // a CS that transforms to a default that we know how to handle
   if (type.getTuple() != null && type.getTuple().getCoordinateSystem() != null) {
     RealTupleType ref = type.getTuple().getCoordinateSystem().getReference();
     if (ref.equals(Display.DisplaySpatialCartesianTuple)
         || ref.equals(Display.DisplayRGBTuple)
         || ref.equals(Display.DisplayFlow1Tuple)
         || ref.equals(Display.DisplayFlow2Tuple)) return true;
   }
   return false;
 }
  /**
   * Sets the RealTupleType of the RGB parameter.
   *
   * @param realTupleType The RealTupleType of the RGB parameters. May not be {@code null}.
   * @throws VisADException VisAD failure.
   * @throws RemoteException Java RMI failure.
   */
  protected void setColorTupleType(RealTupleType realTupleType)
      throws RemoteException, VisADException {

    if (!realTupleType.equals(colorTupleType)) {
      colorTupleType = realTupleType;
      setColorMaps();
    }
  }
  /**
   * Handles internal consequences of a change to the probe position.
   *
   * @param pos The probe's new position.
   */
  public void probeMoved(RealTuple pos) {
    if (!getHaveInitialized()) {
      return;
    }

    try {
      LatLonPoint llp = null;
      RealTupleType rttype = (RealTupleType) pos.getType();

      if (rttype.equals(RealTupleType.SpatialCartesian2DTuple)
          || rttype.equals(RealTupleType.SpatialCartesian3DTuple)) {
        llp = latLon(pos);
      } else if (rttype.equals(RealTupleType.SpatialEarth2DTuple)
          || rttype.equals(RealTupleType.SpatialEarth3DTuple)) {
        Real[] reals = pos.getRealComponents();

        llp = new LatLonTuple(reals[1], reals[0]);
      } else if (rttype.equals(RealTupleType.LatitudeLongitudeTuple)
          || rttype.equals(RealTupleType.LatitudeLongitudeAltitude)) {
        Real[] reals = pos.getRealComponents();

        llp = new LatLonTuple(reals[0], reals[1]);
      } else {
        throw new IllegalArgumentException("Can't convert position to navigable point");
      }

      if (llp != null) {
        dataNode.setLocation(llp); // invokes super.setLocation(llp)
      }
    } catch (Exception ex) {
      logException("probeMoved", ex);
    }
  }
Exemple #9
0
  /**
   * Sets the input, buoyancy profile.
   *
   * @param buoyProfile The input, buoyancy profile.
   * @throws TypeException if the domain quantity isn't pressure or the range quantity isn't volume
   *     per mass.
   * @throws VisADException if a VisAD failure occurs.
   * @throws RemoteException if a Java RMI failure occurs.
   */
  public void setBuoyancyProfile(Field buoyProfile)
      throws TypeException, VisADException, RemoteException {

    FunctionType funcType = (FunctionType) buoyProfile.getType();
    RealTupleType domainType = funcType.getDomain();

    if (!Pressure.getRealType().equalsExceptNameButUnits(domainType)) {
      throw new TypeException(domainType.toString());
    }

    MathType rangeType = funcType.getRange();

    if (!CapeBean.massicVolume.equalsExceptNameButUnits(rangeType)) {
      throw new TypeException(rangeType.toString());
    }

    this.buoyProfile = buoyProfile;
  }
 private static Set getNullDomainSet(RealTupleType type) throws VisADException {
   int n = type.getDimension();
   double[] values = new double[n];
   for (int i = 0; i < n; i++) values[i] = 0.0;
   RealTuple tuple;
   try {
     tuple = new RealTuple(type, values);
     return new SingletonSet(tuple);
   } catch (RemoteException e) {
     throw new VisADError("FileFlatField.getNullDomainSet: " + e.toString());
   }
 }
Exemple #11
0
  /** create parallel coordinates display for data */
  public static void parallel(DisplayImpl display, FlatField data)
      throws VisADException, RemoteException {

    FunctionType ftype = (FunctionType) data.getType();
    RealType index = (RealType) ftype.getDomain().getComponent(0);
    RealTupleType range = (RealTupleType) ftype.getRange();
    int ncoords = range.getDimension();
    int nrows = data.getLength();
    Set index_set = data.getDomainSet();
    float[][] samples = data.getFloats(false);

    RealType x = RealType.getRealType("coordinate");
    RealType y = RealType.getRealType("value");
    SetType xy = new SetType(new RealTupleType(x, y));
    FunctionType ptype = new FunctionType(index, xy);
    FieldImpl pfield = new FieldImpl(ptype, index_set);
    for (int j = 0; j < nrows; j++) {
      float[][] locs = new float[2][ncoords];
      for (int i = 0; i < ncoords; i++) {
        locs[0][i] = i;
        locs[1][i] = samples[i][j];
      }
      Gridded2DSet set = new Gridded2DSet(xy, locs, ncoords);
      pfield.setSample(j, set, false);
    }

    // create a DataReference for river system
    DataReference parallel_ref = new DataReferenceImpl("parallel");
    parallel_ref.setData(pfield);

    display.addMap(new ScalarMap(x, Display.XAxis));
    display.addMap(new ScalarMap(y, Display.YAxis));

    // enable axis scales
    display.getGraphicsModeControl().setScaleEnable(true);

    // link display to parallel display
    display.addReference(parallel_ref);
  }
  /**
   * @param gridWinds
   * @param grid
   * @return
   * @throws IllegalArgumentException if the grid is irregular or has too few points or has no
   *     {@link visad.CoordinateSystem}, or if the reference of the grid's {@link
   *     visad.CoordinateSystem} doesn't contain {@link visad.RealType.Latitude} and {@link
   *     visad.RealType.Longitude}.
   * @throws VisADException
   */
  private static float[][] trueWind(float[][] gridWinds, SampledSet grid) throws VisADException {

    if (grid instanceof IrregularSet) {
      throw new IllegalArgumentException(grid.toString());
    }

    CoordinateSystem cs = grid.getCoordinateSystem();
    boolean hasCS = (cs != null);

    RealTupleType rtt = (hasCS) ? cs.getReference() : ((SetType) grid.getType()).getDomain();

    int latI = rtt.getIndex(RealType.Latitude);

    if (latI == -1) {
      throw new IllegalArgumentException(rtt.toString());
    }

    int lonI = rtt.getIndex(RealType.Longitude);

    if (lonI == -1) {
      throw new IllegalArgumentException(rtt.toString());
    }

    if (grid.getManifoldDimension() < 2) {
      throw new IllegalArgumentException(grid.toString());
    }

    float[] us = new float[grid.getLength()];
    float[] vs = new float[grid.getLength()];

    Arrays.fill(us, 0);
    Arrays.fill(vs, 0);
    addComponent(grid, gridWinds, cs, 0, latI, lonI, us, vs);
    addComponent(grid, gridWinds, cs, 1, latI, lonI, us, vs);

    return new float[][] {us, vs};
  }
  public ImageRGBDisplayable(String name, float[][] colorPalette, boolean doAlpha, FieldImpl field)
      throws VisADException, RemoteException {
    super(name);
    this.doAlpha = doAlpha;
    if (doAlpha) {
      mapType = Display.RGBA;
      colorMaps = new ScalarMap[] {null, null, null, null};
    }

    addConstantMaps(
        new ConstantMap[] {
          new ConstantMap(GraphicsModeControl.SUM_COLOR_MODE, Display.ColorMode),
          new ConstantMap(1.0, Display.MissingTransparent)
        });

    if (field != null) {
      TupleType tt = GridUtil.getParamType(field);
      RealTupleType ffldType = new RealTupleType(tt.getRealComponents());

      if ((getColorTupleType() == null) || !ffldType.equals(getColorTupleType())) {
        setColorTupleType(ffldType);
      }
    }
  }
  /**
   * determine whether the given MathType and collection of ScalarMaps meets the criteria to use
   * ImageRendererJ3D. Throw a VisADException if ImageRenderer cannot be used, otherwise return
   * true.
   */
  public static boolean isRendererUsable(MathType type, ScalarMap[] maps) throws VisADException {
    RealType time = null;
    RealTupleType domain = null;
    RealTupleType range = null;
    RealType x = null, y = null;
    RealType rx = null, ry = null; // WLH 19 July 2000
    RealType r = null, g = null, b = null;
    RealType rgb = null;

    // must be a function
    if (!(type instanceof FunctionType)) {
      throw new VisADException("Not a FunctionType");
    }
    FunctionType function = (FunctionType) type;
    RealTupleType functionD = function.getDomain();
    MathType functionR = function.getRange();

    // time function
    if (function.equalsExceptName(image_sequence_type)
        || function.equalsExceptName(image_sequence_type2)
        || function.equalsExceptName(image_sequence_type3)) {
      // strip off time RealType
      time = (RealType) functionD.getComponent(0);
      function = (FunctionType) functionR;
      functionD = function.getDomain();
      functionR = function.getRange();
    }

    // ((ImageLine, ImageElement) -> ImageValue)
    // ((ImageLine, ImageElement) -> (ImageValue))
    // ((ImageLine, ImageElement) -> (Red, Green, Blue))
    if (function.equalsExceptName(image_type)
        || function.equalsExceptName(image_type2)
        || function.equalsExceptName(image_type3)) {
      domain = function.getDomain();
      MathType rt = function.getRange();
      if (rt instanceof RealType) {
        range = new RealTupleType((RealType) rt);
      } else if (rt instanceof RealTupleType) {
        range = (RealTupleType) rt;
      } else {
        // illegal MathType
        throw new VisADException("Illegal RangeType");
      }
    } else {
      // illegal MathType
      throw new VisADException("Illegal MathType");
    }

    // extract x and y from domain
    x = (RealType) domain.getComponent(0);
    y = (RealType) domain.getComponent(1);

    // WLH 19 July 2000
    CoordinateSystem cs = domain.getCoordinateSystem();
    if (cs != null) {
      RealTupleType rxy = cs.getReference();
      rx = (RealType) rxy.getComponent(0);
      ry = (RealType) rxy.getComponent(1);
    }

    // extract colors from range
    int dim = range.getDimension();
    if (dim == 1) rgb = (RealType) range.getComponent(0);
    else { // dim == 3
      r = (RealType) range.getComponent(0);
      g = (RealType) range.getComponent(1);
      b = (RealType) range.getComponent(2);
    }

    // verify that collection of ScalarMaps is legal
    boolean btime = (time == null);
    boolean bx = false, by = false;
    boolean brx = false, bry = false; // WLH 19 July 2000
    boolean br = false, bg = false, bb = false;
    boolean dbr = false, dbg = false, dbb = false;
    Boolean latlon = null;
    DisplayRealType spatial = null;

    for (int i = 0; i < maps.length; i++) {
      ScalarMap m = maps[i];
      ScalarType md = m.getScalar();
      DisplayRealType mr = m.getDisplayScalar();
      boolean ddt = md.equals(time);
      boolean ddx = md.equals(x);
      boolean ddy = md.equals(y);
      boolean ddrx = md.equals(rx);
      boolean ddry = md.equals(ry);
      boolean ddr = md.equals(r);
      boolean ddg = md.equals(g);
      boolean ddb = md.equals(b);
      boolean ddrgb = md.equals(rgb);

      // animation mapping
      if (ddt) {
        if (btime) throw new VisADException("Multiple Time mappings");
        if (!mr.equals(Display.Animation)) {
          throw new VisADException("Time mapped to something other than Animation");
        }
        btime = true;
      }

      // spatial mapping
      else if (ddx || ddy || ddrx || ddry) {
        if (ddx && bx || ddy && by || ddrx && brx || ddry && bry) {
          throw new VisADException("Duplicate spatial mappings");
        }
        if (((ddx || ddy) && (brx || bry)) || ((ddrx || ddry) && (bx || by))) {
          throw new VisADException("reference and non-reference spatial mappings");
        }
        RealType q = (ddx ? x : null);
        if (ddy) q = y;
        if (ddrx) q = rx;
        if (ddry) q = ry;

        boolean ll;
        if (mr.equals(Display.XAxis) || mr.equals(Display.YAxis) || mr.equals(Display.ZAxis)) {
          ll = false;
        } else if (mr.equals(Display.Latitude)
            || mr.equals(Display.Longitude)
            || mr.equals(Display.Radius)) {
          ll = true;
        } else throw new VisADException("Illegal domain mapping");

        if (latlon == null) {
          latlon = new Boolean(ll);
          spatial = mr;
        } else if (latlon.booleanValue() != ll) {
          throw new VisADException("Multiple spatial coordinate systems");
        }
        // two mappings to the same spatial DisplayRealType are not allowed
        else if (spatial == mr) {
          throw new VisADException("Multiple mappings to the same spatial DisplayRealType");
        }

        if (ddx) bx = true;
        else if (ddy) by = true;
        else if (ddrx) brx = true;
        else if (ddry) bry = true;
      }

      // rgb mapping
      else if (ddrgb) {
        if (br || bg || bb) {
          throw new VisADException("Duplicate color mappings");
        }
        if (rgb == null || !(mr.equals(Display.RGB) || mr.equals(Display.RGBA))) {
          throw new VisADException("Illegal RGB/RGBA mapping");
        }
        dbr = dbg = dbb = true;
        br = bg = bb = true;
      }

      // color mapping
      else if (ddr || ddg || ddb) {
        if (rgb != null) throw new VisADException("Illegal RGB mapping");
        RealType q = (ddr ? r : (ddg ? g : b));
        if (mr.equals(Display.Red)) dbr = true;
        else if (mr.equals(Display.Green)) dbg = true;
        else if (mr.equals(Display.Blue)) dbb = true;
        else throw new VisADException("Illegal color mapping");

        if (ddr) br = true;
        else if (ddg) bg = true;
        else bb = true;
      }

      // illegal ScalarMap involving this MathType
      else if (ddt || ddx || ddy || ddrx || ddry || ddr || ddg || ddb || ddrgb) {
        throw new VisADException("Illegal mapping: " + m);
      }
    }

    // return true if all conditions for ImageRendererJ3D are met
    if (!(btime && ((bx && by) || (brx && bry)) && br && bg && bb && dbr && dbg && dbb)) {
      throw new VisADException("Insufficient mappings");
    }
    return true;
  }
  /**
   * I have no idea what this does.
   *
   * @param grid sampling grid
   * @param index some sort of index
   * @return a new flat field with something different
   * @throws RemoteException Java RMI error
   * @throws VisADException VisAD error
   */
  private static FlatField hatFieldOld(Set grid, int index) throws VisADException, RemoteException {

    CoordinateSystem cs = grid.getCoordinateSystem();
    boolean hasCS = (cs != null);

    RealTupleType rtt = (hasCS) ? cs.getReference() : ((SetType) grid.getType()).getDomain();

    int latI = rtt.getIndex(RealType.Latitude);

    if (latI == -1) {
      throw new IllegalArgumentException(grid.toString());
    }

    int lonI = rtt.getIndex(RealType.Longitude);

    if (lonI == -1) {
      throw new IllegalArgumentException(grid.toString());
    }

    if (grid.getManifoldDimension() < 2) {
      throw new IllegalArgumentException(grid.toString());
    }

    int[][] neighbors = grid.getNeighbors(index);
    LatLonPointImpl refPt = new LatLonPointImpl();
    LatLonPointImpl neiPt = new LatLonPointImpl();
    Bearing bearing = new Bearing();
    float[] hat1 = new float[2];
    float[] hat2 = new float[2];
    float[][] hat = new float[2][grid.getLength()];

    for (int i = 0; i < neighbors.length; i++) {
      float[][] refCoords = grid.indexToValue(new int[] {i});
      if (hasCS) {
        refCoords = cs.toReference(refCoords);
      }

      float[][] neiCoords = grid.indexToValue(neighbors[i]);
      if (hasCS) {
        neiCoords = cs.toReference(neiCoords);
      }

      refPt.set(refCoords[latI][0], refCoords[lonI][0]);
      compute(refPt, neiPt, neiCoords[latI][0], neiCoords[lonI][0], -180, bearing, hat1);

      float d1 = (float) bearing.getDistance();

      compute(refPt, neiPt, neiCoords[latI][1], neiCoords[lonI][1], 0, bearing, hat2);

      float d2 = (float) bearing.getDistance();
      boolean bad1 = Double.isNaN(d1);
      boolean bad2 = Double.isNaN(d2);

      if (bad1 && bad2) {
        hat[0][i] = Float.NaN;
        hat[1][i] = Float.NaN;
      } else {
        if (bad1) {
          hat[0][i] = hat2[0];
          hat[1][i] = hat2[1];
        } else if (bad2) {
          hat[0][i] = hat1[0];
          hat[1][i] = hat1[1];
        } else {
          float tot = d1 + d2;
          float c1 = d2 / tot;
          float c2 = d1 / tot;
          float xhat = c1 * hat1[0] + c2 * hat2[0];
          float yhat = c1 * hat1[1] + c2 * hat2[1];
          float mag = (float) Math.sqrt(xhat * xhat + yhat * yhat);

          hat[0][i] = xhat / mag;
          hat[1][i] = yhat / mag;
        }
      }
    }

    FlatField hatField =
        new FlatField(
            new FunctionType(
                ((SetType) grid.getType()).getDomain(),
                new RealTupleType(
                    RealType.getRealType("xHat", CommonUnit.dimensionless),
                    RealType.getRealType("yHat", CommonUnit.dimensionless))),
            grid);

    hatField.setSamples(hat, false);

    return hatField;
  }
  /**
   * The returned {@link visad.FlatField} will have NaN-s for those unit vector components that
   * could not be computed.
   *
   * @param grid The spatial grid.
   * @param index The index of the manifold dimension along which to compute the unit vector.
   * @return A field of components of the unit vector for the given manifold dimension.
   * @throws NullPointerException if the grid is <code>null</code>.
   * @throws IllegalArgumentException if the manifold dimension of the grid is less than 2 or if the
   *     grid doesn't contain {@link visad.RealType#Latitude} and {@link visad.RealType#Longitude}.
   * @throws VisADException if a VisAD failure occurs.
   * @throws RemoteException if a Java RMI failure occurs.
   */
  private static FlatField hatFieldNew(Set grid, int index) throws VisADException, RemoteException {

    CoordinateSystem cs = grid.getCoordinateSystem();
    boolean hasCS = cs != null;

    RealTupleType rtt = (hasCS) ? cs.getReference() : ((SetType) grid.getType()).getDomain();

    int latI = rtt.getIndex(RealType.Latitude);

    if (latI == -1) {
      throw new IllegalArgumentException(rtt.toString());
    }

    int lonI = rtt.getIndex(RealType.Longitude);
    if (lonI == -1) {
      throw new IllegalArgumentException(rtt.toString());
    }

    if (grid.getManifoldDimension() < 2) {
      throw new IllegalArgumentException(grid.toString());
    }

    int[][] neighbors = grid.getNeighbors(index);
    LatLonPointImpl refPt = new LatLonPointImpl();
    LatLonPointImpl neiPt = new LatLonPointImpl();
    Bearing bearing = new Bearing();
    float[] hat1 = new float[2];
    float[] hat2 = new float[2];
    float[][] hat = new float[2][grid.getLength()];

    float[][] refCoords = null;
    float[][] neiCoords = null;
    float[][] domainSamples = grid.getSamples(false);

    refCoords = (hasCS) ? cs.toReference(Set.copyFloats(domainSamples)) : domainSamples;
    // If the grid is lat/lon or has an IdentityCoordinateSystem
    // don't do the rotation
    // TODO:  handle rotated lat/lon grids
    if (!hasCS
        || (refCoords == domainSamples)
        || (Arrays.equals(refCoords[latI], domainSamples[latI])
            && Arrays.equals(refCoords[lonI], domainSamples[lonI]))) {
      if (index == 0) {
        Arrays.fill(hat[0], 1);
        Arrays.fill(hat[1], 0);
      } else {
        Arrays.fill(hat[0], 0);
        Arrays.fill(hat[1], 1);
      }
    } else {

      float latBefore, lonBefore, latAfter, lonAfter;
      // int backOffset = (index==0) ? -180 : 0;
      // int foreOffset = (index==0) ? 0 : -180;
      int backOffset = -180;
      int foreOffset = 0;
      for (int i = 0; i < neighbors.length; i++) {
        refPt.set(refCoords[latI][i], refCoords[lonI][i]);
        if ((neighbors[i][0] < 0) || (neighbors[i][0] >= neighbors.length)) {
          latBefore = Float.NaN;
          lonBefore = Float.NaN;
        } else {
          latBefore = refCoords[latI][neighbors[i][0]];
          lonBefore = refCoords[lonI][neighbors[i][0]];
        }
        if ((neighbors[i][1] < 0) || (neighbors[i][1] >= neighbors.length)) {
          latAfter = Float.NaN;
          lonAfter = Float.NaN;
        } else {
          latAfter = refCoords[latI][neighbors[i][1]];
          lonAfter = refCoords[lonI][neighbors[i][1]];
        }

        compute(refPt, neiPt, latBefore, lonBefore, backOffset, bearing, hat1);

        float d1 = (float) bearing.getDistance();

        compute(refPt, neiPt, latAfter, lonAfter, foreOffset, bearing, hat2);

        float d2 = (float) bearing.getDistance();
        boolean bad1 = Double.isNaN(d1);
        boolean bad2 = Double.isNaN(d2);

        if (bad1 && bad2) {
          hat[0][i] = Float.NaN;
          hat[1][i] = Float.NaN;
        } else {
          if (bad1) {
            hat[0][i] = hat2[0];
            hat[1][i] = hat2[1];
          } else if (bad2) {
            hat[0][i] = hat1[0];
            hat[1][i] = hat1[1];
          } else {
            float tot = d1 + d2;
            float c1 = d2 / tot;
            float c2 = d1 / tot;
            float xhat = c1 * hat1[0] + c2 * hat2[0];
            float yhat = c1 * hat1[1] + c2 * hat2[1];
            float mag = (float) Math.sqrt(xhat * xhat + yhat * yhat);

            hat[0][i] = xhat / mag;
            hat[1][i] = yhat / mag;
          }
        }
      }
    }

    FlatField hatField =
        new FlatField(
            new FunctionType(
                ((SetType) grid.getType()).getDomain(),
                new RealTupleType(
                    RealType.getRealType("xHat", CommonUnit.dimensionless),
                    RealType.getRealType("yHat", CommonUnit.dimensionless))),
            grid);

    hatField.setSamples(hat, false);
    return hatField;
  }
  /**
   * Converts a time-series of grid-relative winds to a time-series of true (or absolute) winds. The
   * U and V components of true wind are {@link WesterlyWind} and {@link SoutherlyWind},
   * respectively. The domain of the input {@link visad.Field} must be a temporal {@link
   * visad.Gridded1DSet} or a {@link visad.SingletonSet}. The range values of the input {@link
   * visad.Field} must be {@link visad.FlatField}s. The domains of the range {@link
   * visad.FlatField}s must have a manifold dimension of two or greater and they must have a
   * reference system which contains {@link visad.RealType#Latitude} and {@link
   * visad.RealType#Longitude}. The number of components in the range of the {@link
   * visad.FlatField}s must be two. Both components must have units convertible with {@link
   * #DEFAULT_SPEED_UNIT}. The first and second components are assumed to be the wind components in
   * the direction of increasing first and second manifold dimension indexes, respectively. The
   * domains of the {@link visad.FlatField}s must be equal. The {@link visad.Field} returned by this
   * method has the same domain as the input {@link visad.Field}. The range values of the returned
   * {@link visad.Field} are {@link visad.FlatField}s that have the same domain as the input {@link
   * visad.FlatField}s. The {@link visad.MathType} of the range of the returned {@link
   * visad.FlatField}s will be <code>CartesianHorizontalWind.getEarthVectorType()</code>.
   *
   * @param rel The time-series of grid-relative wind.
   * @return The time-series of true wind corresponding to the input.
   * @throws NullPointerException if <code>rel</code> is <code>null</code>.
   * @throws IllegalArgumentException if the input field doesn't have a time-series domain, or if
   *     the range values aren't {@link visad.FlatField} with the same domain, or if the domain of
   *     the {@link visad.FlatField}s doesn't have a transformation to latitude and longitude, or if
   *     the domain is irregular or has too few points, or if the {@link visad.FlatField}s don't
   *     have two and only two components in their range, or if the default units of the {@link
   *     visad.FlatField}s range aren't equal.
   * @throws VisADException if a VisAD failure occurs.
   * @throws RemoteException if a Java RMI failure occurs.
   * @see CartesianHorizontalWind
   */
  public static Field timeSeriesCartesianHorizontalWind(Field rel)
      throws VisADException, RemoteException {

    FunctionType outerFuncType = (FunctionType) rel.getType();
    RealTupleType outerDomType = outerFuncType.getDomain();

    if (!(RealType.Time.equalsExceptNameButUnits(outerDomType)
        || !RealType.TimeInterval.equalsExceptNameButUnits(outerDomType))) {
      throw new IllegalArgumentException(outerDomType.toString());
    }

    MathType innerFuncType = outerFuncType.getRange();

    if (!(innerFuncType instanceof FunctionType)) {
      throw new IllegalArgumentException(innerFuncType.toString());
    }

    Field innerField = (Field) rel.getSample(0);
    Set innerDom = innerField.getDomainSet();
    if (innerDom instanceof SingletonSet) {
      return rel;
    } else if (innerDom instanceof GriddedSet) {
      int[] lengths = ((GriddedSet) innerDom).getLengths();
      if ((lengths[0] == 1) && (lengths[1] == 1)) {
        return rel;
      }
    }

    // account for null units, assume m/sec
    Unit[] rangeUnits = innerField.getDefaultRangeUnits();
    if ((rangeUnits == null) || (rangeUnits[0] == null) || rangeUnits[0].isDimensionless()) {
      rangeUnits = CartesianHorizontalWind.getEarthVectorType().getDefaultUnits();
    }
    FunctionType innerType =
        new FunctionType(
            ((SetType) innerDom.getType()).getDomain(),
            CartesianHorizontalWind.getEarthVectorType());

    FlatField uvField =
        new FlatField(innerType, innerDom, (CoordinateSystem) null, (Set[]) null, rangeUnits);

    Field result =
        new FieldImpl(new FunctionType(outerDomType, uvField.getType()), rel.getDomainSet());

    // System.out.println("making rHatField");
    Field rHatField = (doNewCode ? hatFieldNew(innerDom, 0) : hatFieldOld(innerDom, 0));
    // System.out.println("making sHatField");
    Field sHatField = (doNewCode ? hatFieldNew(innerDom, 1) : hatFieldOld(innerDom, 1));

    float[][] rHats = rHatField.getFloats(false);
    // ucar.unidata.util.Misc.printArray("rHats[0]", rHats[0]);
    // ucar.unidata.util.Misc.printArray("rHats[1]", rHats[1]);
    // System.out.println("\n");
    float[][] sHats = sHatField.getFloats(false);
    // ucar.unidata.util.Misc.printArray("sHats[0]", sHats[0]);
    // ucar.unidata.util.Misc.printArray("sHats[1]", sHats[1]);
    // System.out.println("\n");
    float[] us = new float[innerDom.getLength()];
    float[] vs = new float[us.length];

    for (int i = 0, n = rel.getLength(); i < n; i++) {
      if (i > 0) {
        innerField = (Field) rel.getSample(i);
        Set dom = innerField.getDomainSet();
        if (!innerDom.equals(dom)) {
          // System.out.println("new domain");
          innerDom = dom;
          rHatField = (doNewCode ? hatFieldNew(innerDom, 0) : hatFieldOld(innerDom, 0));
          sHatField = (doNewCode ? hatFieldNew(innerDom, 1) : hatFieldOld(innerDom, 1));

          rHats = rHatField.getFloats(false);
          sHats = sHatField.getFloats(false);
          /*
          throw new IllegalArgumentException("template="
                  + innerDom.toString() + "; domain="
                  + dom.toString());
          */
        }
        uvField =
            new FlatField(innerType, innerDom, (CoordinateSystem) null, (Set[]) null, rangeUnits);
        us = new float[innerDom.getLength()];
        vs = new float[us.length];
      }

      float[][] rsWinds = innerField.getFloats(false);
      float[] rWinds = rsWinds[0];
      float[] sWinds = rsWinds[1];
      // ucar.unidata.util.Misc.printArray("rWinds", rWinds);
      // System.out.println("\n");
      // ucar.unidata.util.Misc.printArray("sWinds", sWinds);
      // System.out.println("\n");

      for (int j = 0; j < us.length; j++) {
        us[j] = rWinds[j] * rHats[0][j] + sWinds[j] * sHats[0][j];
        vs[j] = rWinds[j] * rHats[1][j] + sWinds[j] * sHats[1][j];
      }
      // ucar.unidata.util.Misc.printArray("us", us);
      // System.out.println("\n");
      // ucar.unidata.util.Misc.printArray("vs", vs);
      // System.out.println("\n");

      uvField.setSamples(new float[][] {us, vs}, false);
      result.setSample(i, uvField, false);
    }

    return result;
  }
Exemple #18
0
  void setupServerData(LocalDisplay[] dpys) throws RemoteException, VisADException {
    DefaultFamily df = new DefaultFamily("loader");

    DataReference ref1 = loadFile(df, file1, "img1");
    if (ref1 == null) {
      System.err.println("\"" + file1 + "\" is not a valid file");
      System.exit(1);
      return;
    }

    DataReference ref2 = loadFile(df, file2, "img2");
    if (ref2 == null) {
      System.err.println("\"" + file2 + "\" is not a valid file");
      System.exit(1);
      return;
    }

    FlatField img1 = (FlatField) ref1.getData();
    FlatField img2 = (FlatField) ref2.getData();

    /*
        if (!img1.getType().equals(img2.getType())) {
          System.err.println("Incompatible file types:");
          System.err.println("  " + file1 + ": " + img1.getType());
          System.err.println("  " + file2 + ": " + img2.getType());
          System.exit(1);
          return;
        }
    */

    // compute ScalarMaps from type components
    FunctionType ftype = (FunctionType) img1.getType();
    RealTupleType dtype = ftype.getDomain();
    RealTupleType rtype = (RealTupleType) ftype.getRange();

    /* map domain elements to spatial axes */
    final int dLen = dtype.getDimension();
    for (int i = 0; i < dLen; i++) {
      ScalarType scalT;
      DisplayRealType dpyRT;

      switch (i) {
        case 0:
          dpyRT = Display.XAxis;
          break;
        case 1:
          dpyRT = Display.YAxis;
          break;
        case 2:
          dpyRT = Display.ZAxis;
          break;
        default:
          dpyRT = null;
          break;
      }

      if (dpyRT != null) {
        dpys[0].addMap(new ScalarMap((RealType) dtype.getComponent(i), dpyRT));
      }
    }

    /* map range elements to colors */
    final int rLen = rtype.getDimension();
    for (int i = 0; i < rLen; i++) {
      ScalarType scalT;
      DisplayRealType dpyRT;

      switch (i) {
        case 0:
          dpyRT = Display.Red;
          break;
        case 1:
          dpyRT = Display.Green;
          break;
        case 2:
          dpyRT = Display.Blue;
          break;
        default:
          dpyRT = null;
          break;
      }

      if (dpyRT != null) {
        dpys[0].addMap(new ScalarMap((RealType) rtype.getComponent(i), dpyRT));
      }
    }

    dpys[0].addReference(ref1, null);
    dpys[0].addReference(ref2, null);

    dpys[0].addActivityHandler(new SwitchGIFs(dpys[0]));
  }
Exemple #19
0
  /**
   * Computes the output Level of Free Convection (LFC) from an (AirPressure -> MassicVolume)
   * buoyancy profile.
   *
   * @param datums The input data in the same order as during construction: <code>datums[0]
   *                                  </code> is the input buoyancy profile.
   * @return The pressure at the LFC of the buoyancy profile.
   * @throws ClassCastException if an input data reference has the wrong type of data object.
   * @throws TypeException if a VisAD data object has the wrong type.
   * @throws VisADException if a VisAD failure occurs.
   * @throws RemoteException if a Java RMI failure occurs.
   * @throws IllegalArgumentException if the profile is not ascending.
   */
  protected Data compute(Data[] datums) throws TypeException, VisADException, RemoteException {

    Field buoyProfile = (Field) datums[0];
    Real lfc = noData; // default return value

    if (buoyProfile != null) {
      FunctionType funcType = (FunctionType) buoyProfile.getType();
      RealTupleType domainType = funcType.getDomain();

      if (!Pressure.getRealType().equalsExceptNameButUnits(domainType)) {
        throw new TypeException(domainType.toString());
      }

      MathType rangeType = funcType.getRange();

      Util.vetType(MassicVolume.getRealType(), buoyProfile);

      Set domainSet = buoyProfile.getDomainSet();
      double[] pressures = domainSet.getDoubles()[0];
      float[] buoys = buoyProfile.getFloats()[0];

      if (pressures.length > 1) {
        int lastI = pressures.length - 1;
        boolean ascending = pressures[0] >= pressures[lastI];

        Unit presUnit = domainSet.getSetUnits()[0];
        int i;

        if (ascending) {
          /*
           * For a level of free convection to exist, the lower
           * buoyancy must be negative.
           */
          for (i = 0; (i < buoys.length) && (buoys[i] >= 0); i++) ;

          /*
           * To find the level of free convection, ascend to
           * positive buoyancy.
           */
          while ((++i < buoys.length) && (buoys[i] <= 0)) ;

          if (i < buoys.length) {
            lfc = interpolatePres(pressures[i], buoys[i], pressures[i - 1], buoys[i - 1], presUnit);
          }
        } else {
          /*
           * For a level of free convection to exist, the lower
           * buoyancy must be negative.
           */
          for (i = lastI; (i >= 0) && (buoys[i] >= 0); i--) ;

          /*
           * To find the level of free convection, ascend to
           * positive buoyancy.
           */
          while ((--i >= 0) && (buoys[i] <= 0)) ;

          if (i >= 0) {
            lfc = interpolatePres(pressures[i], buoys[i], pressures[i + 1], buoys[i + 1], presUnit);
          }
        }
      }
    }

    return lfc;
  }
  /**
   * run 'java visad.bom.ImageRendererJ3D len step' to test animation behavior of ImageRendererJ3D
   * renders a loop of len at step ms per frame then updates loop by deleting first time and adding
   * a new last time
   */
  public static void main(String args[]) throws VisADException, RemoteException, IOException {

    int step = 1000;
    int len = 3;
    if (args.length > 0) {
      try {
        len = Integer.parseInt(args[0]);
      } catch (NumberFormatException e) {
        len = 3;
      }
    }
    if (len < 1) len = 1;
    if (args.length > 1) {
      try {
        step = Integer.parseInt(args[1]);
      } catch (NumberFormatException e) {
        step = 1000;
      }
    }
    if (step < 1) step = 1;

    // create a netCDF reader
    Plain plain = new Plain();

    // open a netCDF file containing an image sequence and adapt
    // it to a Field Data object
    Field raw_image_sequence = null;
    try {
      // raw_image_sequence = (Field) plain.open("images256x256.nc");
      raw_image_sequence = (Field) plain.open("images.nc");
    } catch (IOException exc) {
      String s =
          "To run this example, the images.nc file must be "
              + "present in\nthe current directory."
              + "You can obtain this file from:\n"
              + "  ftp://www.ssec.wisc.edu/pub/visad-2.0/images.nc.Z";
      System.out.println(s);
      System.exit(0);
    }

    // just take first half of raw_image_sequence
    FunctionType image_sequence_type = (FunctionType) raw_image_sequence.getType();
    Set raw_set = raw_image_sequence.getDomainSet();
    float[][] raw_times = raw_set.getSamples();
    int raw_len = raw_times[0].length;
    if (raw_len != 4) {
      throw new VisADException("wrong number of images in sequence");
    }
    float raw_span = (4.0f / 3.0f) * (raw_times[0][3] - raw_times[0][0]);

    double[][] times = new double[1][len];
    for (int i = 0; i < len; i++) {
      times[0][i] = raw_times[0][i % raw_len] + raw_span * (i / raw_len);
    }
    Gridded1DDoubleSet set = new Gridded1DDoubleSet(raw_set.getType(), times, len);
    Field image_sequence = new FieldImpl(image_sequence_type, set);
    for (int i = 0; i < len; i++) {
      image_sequence.setSample(i, raw_image_sequence.getSample(i % raw_len));
    }

    // create a DataReference for image sequence
    final DataReference image_ref = new DataReferenceImpl("image");
    image_ref.setData(image_sequence);

    // create a Display using Java3D
    DisplayImpl display = new DisplayImplJ3D("image display");

    // extract the type of image and use
    // it to determine how images are displayed
    FunctionType image_type = (FunctionType) image_sequence_type.getRange();
    RealTupleType domain_type = image_type.getDomain();
    // map image coordinates to display coordinates
    display.addMap(new ScalarMap((RealType) domain_type.getComponent(0), Display.XAxis));
    display.addMap(new ScalarMap((RealType) domain_type.getComponent(1), Display.YAxis));
    // map image brightness values to RGB (default is grey scale)
    display.addMap(new ScalarMap((RealType) image_type.getRange(), Display.RGB));
    RealType hour_type = (RealType) image_sequence_type.getDomain().getComponent(0);
    ScalarMap animation_map = new ScalarMap(hour_type, Display.Animation);
    display.addMap(animation_map);
    AnimationControl animation_control = (AnimationControl) animation_map.getControl();
    animation_control.setStep(step);
    animation_control.setOn(true);

    /*
        // link the Display to image_ref
        ImageRendererJ3D renderer = new ImageRendererJ3D();
        display.addReferences(renderer, image_ref);
        // display.addReference(image_ref);
    */

    // create JFrame (i.e., a window) for display and slider
    JFrame frame = new JFrame("ImageRendererJ3D test");
    frame.addWindowListener(
        new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });

    // create JPanel in JFrame
    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
    panel.setAlignmentY(JPanel.TOP_ALIGNMENT);
    panel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
    frame.getContentPane().add(panel);

    // add display to JPanel
    panel.add(display.getComponent());

    // set size of JFrame and make it visible
    frame.setSize(500, 500);
    frame.setVisible(true);

    System.out.println("first animation sequence");
    // link the Display to image_ref
    ImageRendererJ3D renderer = new ImageRendererJ3D();
    display.addReferences(renderer, image_ref);
    // display.addReference(image_ref);

    // wait 4 * len seconds
    new Delay(len * 4000);

    // substitute a new image sequence for the old one
    for (int i = 0; i < len; i++) {
      times[0][i] = raw_times[0][(i + 1) % raw_len] + raw_span * ((i + 1) / raw_len);
    }
    set = new Gridded1DDoubleSet(raw_set.getType(), times, len);
    FieldImpl new_image_sequence = new FieldImpl(image_sequence_type, set);
    for (int i = 0; i < len; i++) {
      new_image_sequence.setSample(i, raw_image_sequence.getSample((i + 1) % raw_len));
    }

    System.out.println("second animation sequence");

    // tell renderer to resue frames in its scene graph
    renderer.setReUseFrames(true);
    image_ref.setData(new_image_sequence);
  }
  /**
   * Construct a satellite display using the specified McIDAS map file, image source. The image can
   * be displayed on a 3D globe or on a flat rectillinear projection.
   *
   * @param mapFile location of the McIDAS map file (path or URL)
   * @param imageSource location of the image source (path or URL)
   * @param display3D if true, use 3D display, otherwise flat rectillinear
   * @param remap remap the image into a domain over North America
   */
  public SatDisplay(String mapFile, String imageSource, boolean display3D, boolean remap) {
    try {
      //  Read in the map file
      BaseMapAdapter baseMapAdapter;
      if (mapFile.indexOf("://") > 0) // URL specified
      {
        baseMapAdapter = new BaseMapAdapter(new URL(mapFile));
      } else // local disk file
      {
        baseMapAdapter = new BaseMapAdapter(mapFile);
      }

      // Create the display and set up the scalar maps to map
      // data to the display
      ScalarMap latMap; // latitude  -> YAxis
      ScalarMap lonMap; // longitude -> XAxis
      if (display3D) {
        display = new DisplayImplJ3D("display");
        latMap = new ScalarMap(RealType.Latitude, Display.Latitude);
        lonMap = new ScalarMap(RealType.Longitude, Display.Longitude);
      } else {
        display = new DisplayImplJ3D("display", new TwoDDisplayRendererJ3D());
        latMap = new ScalarMap(RealType.Latitude, Display.YAxis);
        lonMap = new ScalarMap(RealType.Longitude, Display.XAxis);
      }
      display.addMap(latMap);
      display.addMap(lonMap);

      // set the display to a global scale
      latMap.setRange(-90.0, 90.0);
      lonMap.setRange(-180.0, 180.0);

      // create a reference for the map line
      DataReference maplinesRef = new DataReferenceImpl("MapLines");
      maplinesRef.setData(baseMapAdapter.getData());

      // set the attributes of the map lines (color, location)
      ConstantMap[] maplinesConstantMap = new ConstantMap[4];
      maplinesConstantMap[0] = new ConstantMap(0., Display.Blue);
      maplinesConstantMap[1] = new ConstantMap(1., Display.Red);
      maplinesConstantMap[2] = new ConstantMap(0., Display.Green);
      maplinesConstantMap[3] = new ConstantMap(1.001, Display.Radius); // just above the image

      // read in the image
      AreaAdapter areaAdapter = new AreaAdapter(imageSource);
      FlatField image = areaAdapter.getData();

      // Extract the metadata from the image
      FunctionType imageFunctionType = (FunctionType) image.getType();
      RealTupleType imageDomainType = imageFunctionType.getDomain();
      RealTupleType imageRangeType = (RealTupleType) imageFunctionType.getRange();

      // remap and resample the image
      if (remap) {
        int SIZE = 256;
        RealTupleType latlonType =
            ((CoordinateSystem) imageDomainType.getCoordinateSystem()).getReference();
        Linear2DSet remapDomainSet =
            new Linear2DSet(latlonType, -4.0, 70.0, SIZE, -150.0, 5.0, SIZE);
        image = (FlatField) image.resample(remapDomainSet, Data.NEAREST_NEIGHBOR, Data.NO_ERRORS);
      }

      // select which band to show...
      ScalarMap rgbMap = new ScalarMap((RealType) imageRangeType.getComponent(0), Display.RGB);
      display.addMap(rgbMap);

      // set the enhancement to a grey scale
      ColorControl colorControl = (ColorControl) rgbMap.getControl();
      colorControl.initGreyWedge();

      // create a data reference for the image
      DataReferenceImpl imageRef = new DataReferenceImpl("ImageRef");
      imageRef.setData(image);

      // add the data references to the display
      display.disableAction();
      drmap = new DefaultRendererJ3D();
      drimage = new DefaultRendererJ3D();
      drmap.toggle(false);
      drimage.toggle(false);
      display.addDisplayListener(this);

      display.addReferences(drmap, maplinesRef, maplinesConstantMap);
      display.addReferences(drimage, imageRef, null);
      display.enableAction();
    } catch (Exception ne) {
      ne.printStackTrace();
      System.exit(1);
    }
  }