/** * _more_ * * @param stormTrack _more_ * @param param _more_ * @return _more_ */ protected LineState makeLine(StormTrack stormTrack, StormParam param) { List<Real> values = new ArrayList<Real>(); List<DateTime> times = stormTrack.getTrackTimes(); List<StormTrackPoint> trackPoints = stormTrack.getTrackPoints(); double min = 0; double max = 0; Unit unit = null; for (int pointIdx = 0; pointIdx < times.size(); pointIdx++) { Real value = trackPoints.get(pointIdx).getAttribute(param); if (value == null) { continue; } if (unit == null) { unit = ((RealType) value.getType()).getDefaultUnit(); } values.add(value); double dvalue = value.getValue(); // System.err.print(","+dvalue); if ((pointIdx == 0) || (dvalue > max)) { max = dvalue; } if ((pointIdx == 0) || (dvalue < min)) { min = dvalue; } } if (values.size() == 0) { return null; } // System.err.println(""); String paramLabel = param.toString(); String label = stormTrack.getWay().toString(); // +":" + paramLabel; LineState lineState = new LineState(); lineState.setRangeIncludesZero(true); if (stormTrack.getWay().isObservation()) { lineState.setWidth(2); } else { lineState.setWidth(1); } lineState.setRange(new Range(min, max)); lineState.setChartName(paramLabel); lineState.setAxisLabel("[" + unit + "]"); // System.err.println (param + " " + StormDataSource.TYPE_STORMCATEGORY); if (Misc.equals(param, StormDataSource.PARAM_STORMCATEGORY)) { // lineState.setShape(LineState.LINETYPE_BAR); lineState.setLineType(LineState.LINETYPE_BAR); lineState.setLineType(LineState.LINETYPE_AREA); } else { lineState.setLineType(LineState.LINETYPE_SHAPES_AND_LINES); lineState.setShape(LineState.SHAPE_LARGEPOINT); } lineState.setColor(stormDisplayState.getWayDisplayState(stormTrack.getWay()).getColor()); lineState.setName(label); lineState.setTrack(times, values); return lineState; }
/** evaluate the bracket function; e.g., A1[5] or A1[A2] */ public static Data brackets(visad.Field f, Real r) { Data value = null; try { RealType rt = (RealType) r.getType(); value = f.getSample((int) r.getValue()); } catch (VisADException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } catch (RemoteException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } return value; }
/** * Does the pattern match the given value * * @param value value to check * @return Pattern matches value */ public boolean match(Data value) throws Exception { if (value instanceof Real && isNumericRange()) { Real[] range = getNumericRange(); Real r = (Real) value; if (r.__ge__(range[0]) == 0) return false; if (r.__le__(range[1]) == 0) return false; return true; } String stringValue = value.toString(); return StringUtil.stringMatch(stringValue, pattern, true, true); }
/** * The animation changed. Handle the change. * * @param evt The event */ private void handleAnimationPropertyChange(PropertyChangeEvent evt) { // System.err.println ("Handlechange:" +evt.getPropertyName()); if (evt.getPropertyName().equals(Animation.ANI_VALUE)) { debug("handleAnimationPropertyChange value :" + evt.getPropertyName()); Real eventValue = (Real) evt.getNewValue(); // if there's nothing to do, return; if ((eventValue == null) || eventValue.isMissing()) { return; } /** The Animation associated with this widget */ DateTime time = null; try { time = new DateTime(eventValue); } catch (VisADException ve) {; } final DateTime theDateTime = time; final int theIndex = ((anime != null) ? anime.getCurrent() : -1); SwingUtilities.invokeLater( new Runnable() { public void run() { boolean oldValue = ignoreTimesCbxEvents; try { ignoreTimesCbxEvents = true; // synchronized (timesCbxMutex) { xcnt++; timesCbx.setSelectedItem(theDateTime); // } if ((boxPanel != null) && (theIndex >= 0)) { boxPanel.setOnIndex(theIndex); } timesCbx.repaint(); } finally { ignoreTimesCbxEvents = oldValue; } } }); shareValue(); } else if (evt.getPropertyName().equals(Animation.ANI_SET)) { if (ignoreAnimationSetChange) { return; } updateIndicatorInner((Set) evt.getNewValue(), true); } }
/** evaluate the extract function */ public static Data extract(visad.Field f, Real r) { Data d = null; try { d = f.extract((int) r.getValue()); } catch (VisADException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } catch (RemoteException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } return d; }
/** evaluate the dot operator */ public static Data dot(TupleIface t, Real r) { Data d = null; try { d = t.getComponent((int) r.getValue()); } catch (VisADException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } catch (RemoteException exc) { if (FormulaVar.DEBUG) exc.printStackTrace(); } return d; }
/** * Add to the properties list * * @param comps List of label/widgets * @param compMap Optional mapping to hold components for later access */ protected void getPropertiesComponents(List comps, Hashtable compMap) { super.getPropertiesComponents(comps, compMap); startTextFld = new JTextField(startText, 5); endTextFld = new JTextField(endText, 5); comps.add(GuiUtils.rLabel("Start Label:")); comps.add(GuiUtils.left(startTextFld)); comps.add(GuiUtils.rLabel("End Label:")); comps.add(GuiUtils.left(endTextFld)); maxDistanceFld = null; tvm = null; if (viewDescriptor != null) { VMManager vmManager = control.getControlContext().getIdv().getVMManager(); List vms = vmManager.getViewManagers(TransectViewManager.class); tvm = (TransectViewManager) VMManager.findViewManagerInList(viewDescriptor, vms); if ((tvm != null) && (maxDataDistance != null)) { maxDistanceFld = new JTextField(maxDataDistance.getValue() + " [" + maxDataDistance.getUnit() + "]", 15); maxDistanceFld.setToolTipText("Maximum distance shown. e.g.: value[unit]"); comps.add(GuiUtils.rLabel("Max distance:")); comps.add(GuiUtils.left(maxDistanceFld)); } } }
/** * Check if we need to show/hide the max data distance box * * @throws RemoteException On badness * @throws VisADException On badness */ public void checkBoxVisibility() throws VisADException, RemoteException { if (maxDistanceBox == null) { return; } if ((maxDataDistance == null) || !super.isVisible()) { maxDistanceBox.setVisible(false); } else { double km = maxDataDistance.getValue(CommonUnit.meter) / 1000.0; if (km > 2000) { maxDistanceBox.setVisible(false); } else { if (control != null) { maxDistanceBox.setVisible(control.shouldBeVisible(this)); } } } }
/** * Find pre-determined contouring values for this parameter by name from the paramdefaults.xml * file, or compute reasonable values of contouring values from the data itself. min no contour * line below this value; base a contour line must have this value (even if not seen), other * values are this value +/- some multiple of the interval; max no contour with greater value than * this; interval if negative, means show dashed lines below base value. * * @param paramName variable name from the data source * @param rangeType one of them ViaAD RealType thingys for the data * @param displayUnit the unit the data will appear on screen * @param range The range * @param contourInfo Default contour info * @return a ContourInfo object with appropriate contouring values */ public ContourInfo findContourInfo( String paramName, RealType rangeType, Unit displayUnit, Range range, ContourInfo contourInfo) { // make an empty ContourInfo object if (contourInfo == null) { contourInfo = new ContourInfo(Double.NaN, Double.NaN, Double.NaN, Double.NaN); } // Find pre-determined contour values for this parameter name ContourInfo dflt = getParamDefaultsEditor().getParamContourInfo(paramName); if (dflt != null) { // Set pre-determined values into local data "contourInfo" // System.out.println(" DC: findContourInfo got params contouring values "+ dflt.toString() // ); contourInfo.setIfDefined(dflt); } if (contourInfo.isDefined()) { return contourInfo; } float min = 0.0f; float max = 1100.0f; float clBase = Float.NaN; float clInterval = Float.NaN; float clMin = Float.NaN; float clMax = Float.NaN; try { // convert data's max/min values from native units to display units // as seen by user in plots; use VisAD methods if (Unit.canConvert(rangeType.getDefaultUnit(), displayUnit)) { Real dispVal = new Real(rangeType, range.min); min = (float) dispVal.getValue(displayUnit); dispVal = new Real(rangeType, range.max); max = (float) dispVal.getValue(displayUnit); } else { min = (float) range.min; max = (float) range.max; } // use data max and min values in display units to find appropriate // workable values for contour interval, base, min, and max. double span = Math.abs(max - min); // GEMPAK alogrithm for 5 to 10 contours in a field from grcval.f int scale = (int) (Math.log(span) / Math.log(10)); if (span < 1) { scale = scale - 1; } double cscale = Math.pow(10, scale); double crange = span / cscale; int nrange = (int) crange; double rint = (nrange + 1) * .1 * cscale; if (Double.isInfinite(rint)) { rint = span; } if ((span <= 300.0) && (span > 5.0)) { /* typical case */ clInterval = (float) rint; clMin = clBase = clInterval * ((int) (min / clInterval)); clMax = clInterval * (1 + (int) (max / clInterval)); } else if (span <= 5.0) { // for max-min less than 5 clInterval = (float) rint; clMin = clBase = min; clMax = max; } else { // for really big ranges, span > 300 make ints clInterval = (float) ((int) rint); clMin = clBase = (float) ((int) min); clMax = (float) ((int) max); } clMax = clMax + clInterval; clMin = clMin - clInterval; } catch (Exception exp) { logException("Set contour levels for " + paramName, exp); } // this should never be true; must be a leftover if (clInterval == 0.0f) { // System.out.println(" DC: findContourInfo got default contour interval of 20.0"); clInterval = 20.0f; } // IF any contouring values were not supplied by the parameter-name-based // information; then load in the computed values made here. if (!contourInfo.getIntervalDefined() && (contourInfo.getLevelsString() == null)) { contourInfo.setInterval(clInterval); } if (!contourInfo.getBaseDefined()) { contourInfo.setBase(clBase); } if (!contourInfo.getMinDefined()) { contourInfo.setMin(clMin); } if (!contourInfo.getMaxDefined()) { contourInfo.setMax(clMax); } return contourInfo; }
/** * Format an Altitude * * @param alt The altitude * @return The formatted alt */ public String formatAltitude(Real alt) { return formatDistance(alt.getValue()); }
/** * Format an lat or lon with cardinal id (N,S,E,W) * * @param latorlon The lat or lon * @param type (LATITUDE or LONGITUDE) * @return The formatted lat or lon */ public String formatLatLonCardinal(Real latorlon, int type) { return formatLatLonCardinal(latorlon.getValue(), type); }
/** * Format an lat or lon * * @param latorlon The lat or lon * @return The formatted lat or lon */ public String formatLatLon(Real latorlon) { return formatLatLon(latorlon.getValue()); }
public synchronized void drag_direct(VisADRay ray, boolean first, int mouseModifiers) { if (barbValues == null || ref == null || shadow == null) return; if (first) { stop = false; } else { if (stop) return; } // modify direction if mshift != 0 // modify speed if mctrl != 0 // modify speed and direction if neither int mshift = mouseModifiers & InputEvent.SHIFT_MASK; int mctrl = mouseModifiers & InputEvent.CTRL_MASK; float o_x = (float) ray.position[0]; float o_y = (float) ray.position[1]; float o_z = (float) ray.position[2]; float d_x = (float) ray.vector[0]; float d_y = (float) ray.vector[1]; float d_z = (float) ray.vector[2]; if (pickCrawlToCursor) { if (first) { offset_count = OFFSET_COUNT_INIT; } else { if (offset_count > 0) offset_count--; } if (offset_count > 0) { float mult = ((float) offset_count) / ((float) OFFSET_COUNT_INIT); o_x += mult * offsetx; o_y += mult * offsety; o_z += mult * offsetz; } } if (first || refirst) { point_x = barbValues[2]; point_y = barbValues[3]; point_z = 0.0f; line_x = 0.0f; line_y = 0.0f; line_z = 1.0f; // lineAxis == 2 in DataRenderer.drag_direct } // end if (first || refirst) float[] x = new float[3]; // x marks the spot // DirectManifoldDimension = 2 // intersect ray with plane float dot = (point_x - o_x) * line_x + (point_y - o_y) * line_y + (point_z - o_z) * line_z; float dot2 = d_x * line_x + d_y * line_y + d_z * line_z; if (dot2 == 0.0) return; dot = dot / dot2; // x is intersection x[0] = o_x + dot * d_x; x[1] = o_y + dot * d_y; x[2] = o_z + dot * d_z; /* System.out.println("x = " + x[0] + " " + x[1] + " " + x[2]); */ try { Tuple data = (Tuple) link.getData(); int n = ((TupleType) data.getType()).getNumberOfRealComponents(); Real[] reals = new Real[n]; int k = 0; int m = data.getDimension(); for (int i = 0; i < m; i++) { Data component = data.getComponent(i); if (component instanceof Real) { reals[k++] = (Real) component; } else if (component instanceof RealTuple) { for (int j = 0; j < ((RealTuple) component).getDimension(); j++) { reals[k++] = (Real) ((RealTuple) component).getComponent(j); } } } if (first || refirst) { // get first Data flow vector for (int i = 0; i < 3; i++) { int j = flowToComponent[i]; data_flow[i] = (j >= 0) ? (float) reals[j].getValue() : 0.0f; } if (coord != null) { float[][] ds = {{data_flow[0]}, {data_flow[1]}, {data_flow[2]}}; ds = coord.toReference(ds); data_flow[0] = ds[0][0]; data_flow[1] = ds[1][0]; data_flow[2] = ds[2][0]; } data_speed = (float) Math.sqrt( data_flow[0] * data_flow[0] + data_flow[1] * data_flow[1] + data_flow[2] * data_flow[2]); float barb0 = barbValues[2] - barbValues[0]; float barb1 = barbValues[3] - barbValues[1]; /* System.out.println("data_flow = " + data_flow[0] + " " + data_flow[1] + " " + data_flow[2]); System.out.println("barbValues = " + barbValues[0] + " " + barbValues[1] + " " + barbValues[2] + " " + barbValues[3]); System.out.println("data_speed = " + data_speed); */ } // end if (first || refirst) // convert x to a flow vector, and from spatial to earth if (getRealVectorTypes(which_barb) instanceof EarthVectorType) { // don't worry about vector magnitude - // data_speed & display_speed take care of that float eps = 0.0001f; // estimate derivative with a little vector float[][] spatial_locs = { {barbValues[0], barbValues[0] + eps * (x[0] - barbValues[0])}, {barbValues[1], barbValues[1] + eps * (x[1] - barbValues[1])}, {0.0f, 0.0f} }; /* System.out.println("spatial_locs = " + spatial_locs[0][0] + " " + spatial_locs[0][1] + " " + spatial_locs[1][0] + " " + spatial_locs[1][1]); */ float[][] earth_locs = spatialToEarth(spatial_locs); // WLH - 18 Aug 99 if (earth_locs == null) return; /* System.out.println("earth_locs = " + earth_locs[0][0] + " " + earth_locs[0][1] + " " + earth_locs[1][0] + " " + earth_locs[1][1]); */ x[2] = 0.0f; x[0] = (earth_locs[1][1] - earth_locs[1][0]) * ((float) Math.cos(Data.DEGREES_TO_RADIANS * earth_locs[0][0])); x[1] = earth_locs[0][1] - earth_locs[0][0]; /* System.out.println("x = " + x[0] + " " + x[1] + " " + x[2]); */ } else { // if (!(getRealVectorTypes(which_barb) instanceof EarthVectorType)) // convert x to vector x[0] -= barbValues[0]; x[1] -= barbValues[1]; // adjust for spatial map scalings but don't worry about vector // magnitude - data_speed & display_speed take care of that // also, spatial is Cartesian double[] ranges = getRanges(); for (int i = 0; i < 3; i++) { x[i] /= ranges[i]; } /* System.out.println("ranges = " + ranges[0] + " " + ranges[1] + " " + ranges[2]); System.out.println("x = " + x[0] + " " + x[1] + " " + x[2]); */ } // WLH 6 August 99 x[0] = -x[0]; x[1] = -x[1]; x[2] = -x[2]; /* may need to do this for performance float[] xx = {x[0], x[1], x[2]}; addPoint(xx); */ float x_speed = (float) Math.sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); /* WLH 16 April 2002 - from Ken if (x_speed < 0.000001f) x_speed = 0.000001f; */ if (x_speed < 0.01f) x_speed = 0.01f; if (first || refirst) { display_speed = x_speed; } refirst = false; if (mshift != 0) { // only modify data_flow direction float ratio = data_speed / x_speed; x[0] *= ratio; x[1] *= ratio; x[2] *= ratio; /* System.out.println("direction, ratio = " + ratio + " " + data_speed + " " + x_speed); System.out.println("x = " + x[0] + " " + x[1] + " " + x[2]); */ } else if (mctrl != 0) { // only modify data_flow speed float ratio = x_speed / display_speed; if (data_speed < EPS) { data_flow[0] = 2.0f * EPS; refirst = true; } x[0] = ratio * data_flow[0]; x[1] = ratio * data_flow[1]; x[2] = ratio * data_flow[2]; /* System.out.println("speed, ratio = " + ratio + " " + x_speed + " " + display_speed); System.out.println("x = " + x[0] + " " + x[1] + " " + x[2]); */ } else { // modify data_flow speed and direction float ratio = data_speed / display_speed; /* System.out.println("data_speed = " + data_speed + " display_speed = " + display_speed + " ratio = " + ratio + " EPS = " + EPS); System.out.println("x = " + x[0] + " " + x[1] +" " + x[2] + " x_speed = " + x_speed); data_speed = 21.213203 display_speed = 0.01 ratio = 2121.3203 EPS = 0.2 x = 1.6170928E-4 1.6021729E-4 -0.0 x_speed = 0.01 wind = (0.3430372, 0.33987218) at (-35.0, 5.0) */ if (data_speed < EPS) { data_flow[0] = 2.0f * EPS; x[0] = data_flow[0]; x[1] = data_flow[1]; x[2] = data_flow[2]; refirst = true; } else { x[0] *= ratio; x[1] *= ratio; x[2] *= ratio; } } if (coord != null) { float[][] xs = {{x[0]}, {x[1]}, {x[2]}}; xs = coord.fromReference(xs); x[0] = xs[0][0]; x[1] = xs[1][0]; x[2] = xs[2][0]; } // now replace flow values Vector vect = new Vector(); for (int i = 0; i < 3; i++) { int j = flowToComponent[i]; if (j >= 0) { RealType rtype = (RealType) reals[j].getType(); reals[j] = new Real(rtype, (double) x[i], rtype.getDefaultUnit(), null); // WLH 31 Aug 2000 Real r = reals[j]; Unit overrideUnit = null; if (directMap[i] != null) { overrideUnit = directMap[i].getOverrideUnit(); } Unit rtunit = rtype.getDefaultUnit(); // units not part of Time string if (overrideUnit != null && !overrideUnit.equals(rtunit) && !RealType.Time.equals(rtype)) { double d = (float) overrideUnit.toThis((double) x[0], rtunit); r = new Real(rtype, d, overrideUnit); String valueString = r.toValueString(); vect.addElement(rtype.getName() + " = " + valueString); } else { // create location string vect.addElement(rtype.getName() + " = " + x[i]); } } } getDisplayRenderer().setCursorStringVector(vect); Data newData = null; // now build new RealTuple or Flat Tuple if (data instanceof RealTuple) { newData = new RealTuple( ((RealTupleType) data.getType()), reals, ((RealTuple) data).getCoordinateSystem()); } else { Data[] new_components = new Data[m]; k = 0; for (int i = 0; i < m; i++) { Data component = data.getComponent(i); if (component instanceof Real) { new_components[i] = reals[k++]; } else if (component instanceof RealTuple) { Real[] sub_reals = new Real[((RealTuple) component).getDimension()]; for (int j = 0; j < ((RealTuple) component).getDimension(); j++) { sub_reals[j] = reals[k++]; } new_components[i] = new RealTuple( ((RealTupleType) component.getType()), sub_reals, ((RealTuple) component).getCoordinateSystem()); } } newData = new Tuple(new_components, false); } ref.setData(newData); } catch (VisADException e) { // do nothing System.out.println("drag_direct " + e); e.printStackTrace(); } catch (RemoteException e) { // do nothing System.out.println("drag_direct " + e); e.printStackTrace(); } }
/** * Handle glyph moved * * @throws RemoteException On badness * @throws VisADException On badness */ public void updateLocation() throws VisADException, RemoteException { super.updateLocation(); if (points.size() < 2) { return; } if (showText) { setText(startTextDisplayable, 0, startText, startTextType); setText(endTextDisplayable, 1, endText, endTextType); } checkBoxVisibility(); if ((maxDataDistance == null) || (maxDistanceBox == null)) { return; } double km = maxDataDistance.getValue(CommonUnit.meter) / 1000.0; if (km > 2000) { return; } EarthLocation p1 = (EarthLocation) points.get(0); EarthLocation p2 = (EarthLocation) points.get(1); MathType mathType = RealTupleType.LatitudeLongitudeAltitude; Bearing baseBearing = Bearing.calculateBearing( p1.getLatitude().getValue(), p1.getLongitude().getValue(), p2.getLatitude().getValue(), p2.getLongitude().getValue(), null); double baseAngle = baseBearing.getAngle(); LatLonPointImpl[] llps = new LatLonPointImpl[] { Bearing.findPoint( p1.getLatitude().getValue(), p1.getLongitude().getValue(), baseAngle + 90.0, km, null), Bearing.findPoint( p2.getLatitude().getValue(), p2.getLongitude().getValue(), baseAngle + 90.0, km, null), Bearing.findPoint( p2.getLatitude().getValue(), p2.getLongitude().getValue(), baseAngle - 90, km, null), Bearing.findPoint( p1.getLatitude().getValue(), p1.getLongitude().getValue(), baseAngle - 90, km, null), Bearing.findPoint( p1.getLatitude().getValue(), p1.getLongitude().getValue(), baseAngle + 90.0, km, null) }; float[][] lineVals = getPointValues(); float alt = lineVals[2][0]; lineVals = new float[3][llps.length]; for (int i = 0; i < lineVals[0].length; i++) { lineVals[0][i] = (float) llps[i].getLatitude(); lineVals[1][i] = (float) llps[i].getLongitude(); } float[][] tmp = new float[3][]; for (int i = 0; i < lineVals[0].length - 1; i++) { tmp[0] = Misc.merge( tmp[0], Misc.interpolate( 2 + getNumInterpolationPoints(), lineVals[0][i], lineVals[0][i + 1])); tmp[1] = Misc.merge( tmp[1], Misc.interpolate( 2 + getNumInterpolationPoints(), lineVals[1][i], lineVals[1][i + 1])); } tmp[2] = new float[tmp[0].length]; lineVals = tmp; for (int i = 0; i < lineVals[0].length; i++) { lineVals[2][i] = alt; } Data theData = new Gridded3DSet(mathType, lineVals, lineVals[0].length); maxDistanceBox.setData(theData); }
/** * Computes the output property. A {@link java.beans.PropertyChangeEvent} is fired for the output * property if it differs from the previous value. * * @throws VisADException if a VisAD failure occurs. * @throws RemoteException if a Java RMI exception occurs. */ void clock() throws VisADException, RemoteException { Set domainSet = buoyProfile.getDomainSet(); Real oldLfc; Real newLfc; double[] pressures = domainSet.getDoubles()[0]; float[] buoys = buoyProfile.getFloats()[0]; /* Eliminate non-finite pressures and buoyancies. */ int n = 0; for (int i = 0; i < pressures.length; i++) { if ((pressures[i] != pressures[i]) || (buoys[i] != buoys[i])) { n++; } } if (n > 0) { double[] tmpPres = new double[pressures.length - n]; float[] tmpBuoy = new float[tmpPres.length]; n = 0; for (int i = 0; i < pressures.length; i++) { if ((pressures[i] != pressures[i]) || (buoys[i] != buoys[i])) { continue; } tmpPres[n] = pressures[i]; tmpBuoy[n] = buoys[i]; n++; } pressures = tmpPres; buoys = tmpBuoy; } if (pressures.length <= 1) { newLfc = missingLfc; } else { Unit presUnit = domainSet.getSetUnits()[0]; boolean ascending = pressures[0] > pressures[1]; if (!ascending) { /* * The profile is descending. Make the temporary value arrays * ascending. */ for (int i = 0, j = pressures.length; i < pressures.length / 2; i++) { --j; double pres = pressures[i]; pressures[i] = pressures[j]; pressures[j] = pres; float buoy = buoys[i]; buoys[i] = buoys[j]; buoys[j] = buoy; } } /* * Descend from the top to positive buoyancy. */ int i = buoys.length; while ((--i >= 0) && (buoys[i] <= 0)) ; if (i < 0) { /* * There is no positively buoyant region. */ newLfc = missingLfc; } else { /* * Descend to first non-positive buoyant region. */ while ((--i >= 0) && (buoys[i] > 0)) ; if (i < 0) { /* * There is no non-positive buoyant region. */ newLfc = missingLfc; } else { /* * Interpolate the LFC. */ double pressure = pressures[i + 1] / Math.exp( buoys[i + 1] * (Math.log(pressures[i] / pressures[i + 1]) / (buoys[i] - buoys[i + 1]))); newLfc = new Real((RealType) missingLfc.getType(), pressure, presUnit); } } } synchronized (this) { oldLfc = lfc; lfc = newLfc; } firePropertyChange(OUTPUT_PROPERTY_NAME, oldLfc, newLfc); }