/*
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
*/
/*
RH looks interesting up to 10000 m
MR better near boundary layer (but tighter color range)
*/
package visad.aeri;
import visad.*;
import visad.util.*;
import visad.DisplayImpl;
import visad.java3d.DisplayImplJ3D;
import visad.data.netcdf.*;
import visad.bom.WindPolarCoordinateSystem;
import visad.data.mcidas.BaseMapAdapter;
import visad.data.mcidas.AreaAdapter;
import visad.meteorology.ImageSequenceManager;
import visad.meteorology.NavigatedImage;
import visad.meteorology.ImageSequence;
import java.rmi.RemoteException;
import java.io.IOException;
import java.io.File;
import visad.data.visad.VisADSerialForm;
// JFC packages
import javax.swing.*;
// AWT packages
import java.awt.*;
import java.awt.event.*;
public class Aeri
implements ScalarMapListener
{
RealType latitude;
RealType longitude;
RealType altitude;
//- (lon,lat,alt)
//
RealTupleType spatial_domain;
RealType time;
RealType stn_idx;
RealType temp;
RealType dwpt;
RealType wvmr;
RealType RH;
RealType theta;
RealType thetaE;
RealType band1 = null;
//- (T,TD,WV,AGE)
//
RealTupleType advect_range;
FunctionType advect_type;
FunctionType advect_field_type;
FieldImpl advect_field;
FieldImpl stations_field;
ImageSequence image_seq;
int n_stations = 5;
double[] station_lat;
double[] station_lon;
double[] station_alt;
double[] station_id;
BaseMapAdapter baseMap;
DataReference map_ref;
DataReference img_ref;
ScalarMap xmap;
ScalarMap ymap;
ScalarMap zmap;
ScalarMap img_map;
boolean xmapEvent = false;
boolean ymapEvent = false;
boolean imgEvent = false;
boolean first_xy_Event = false;
boolean first_img_Event = false;
float latmin, latmax;
float lonmin, lonmax;
float del_lat, del_lon;
double[] x_range, y_range;
int height_limit = 3000; // meters
boolean rh = false;
boolean tm = false;
boolean pt = false;
boolean ept = false;
int start_date = 0;
double start_time = 0.0;
public static void main(String args[])
throws VisADException, RemoteException, IOException
{
Aeri aeri = new Aeri(args);
}
public Aeri(String[] args)
throws VisADException, RemoteException, IOException
{
String vadfile = null;
String baseDate = "20000112";
for (int i=0; i hgt) hgt = hi[2];
if (!any && samples[0][0] == samples[0][0] &&
samples[1][0] == samples[1][0]) {
any = true;
locs[0][0] = samples[0][0];
locs[1][0] = samples[1][0];
locs[0][1] = samples[0][0];
locs[1][1] = samples[1][0];
if (samples[0][0] > lat_max) lat_max = samples[0][0];
if (samples[0][0] < lat_min) lat_min = samples[0][0];
if (samples[1][0] > lon_max) lon_max = samples[1][0];
if (samples[1][0] < lon_min) lon_min = samples[1][0];
}
}
if (any) {
locs[2][0] = 0.0f;
locs[2][1] = hgt;
set_s[ii++] = new Gridded3DSet(spatial_domain, locs, 2, null, null, null);
// System.out.println("set_s[" + kk + "] = " + set_s[kk]);
if (hgt > hgt_max) hgt_max = hgt;
}
}
SampledSet[] set_ss = new SampledSet[ii];
System.arraycopy(set_s, 0, set_ss, 0, ii);
return new UnionSet(spatial_domain, set_ss);
}
public void mapChanged(ScalarMapEvent e)
throws VisADException, RemoteException
{
if ( xmap.equals(e.getScalarMap()) ) {
xmapEvent = true;
}
else if ( ymap.equals(e.getScalarMap()) ) {
ymapEvent = true;
}
else if ( img_map.equals(e.getScalarMap()) ) {
imgEvent = true;
}
if (( xmapEvent && ymapEvent ) && !(first_xy_Event) ) {
x_range = xmap.getRange();
y_range = ymap.getRange();
latmin = (float)y_range[0];
latmax = (float)y_range[1];
lonmin = (float)x_range[0];
lonmax = (float)x_range[1];
baseMap.setLatLonLimits(latmin-del_lat, latmax+del_lat,
lonmin-del_lon, lonmax+del_lon);
DataImpl map = baseMap.getData();
map_ref.setData(map);
first_xy_Event = true;
xmap.setRange(lonmin, lonmax);
ymap.setRange(latmin, latmax);
img_ref.setData(image_seq);
}
if ( imgEvent && !first_img_Event ) {
double[] i_range = img_map.getRange();
System.out.println(i_range[0]+" "+i_range[1]);
first_img_Event = true;
img_map.setRange(i_range[1], i_range[0]);
}
}
public void controlChanged(ScalarMapControlEvent e)
{
}
FieldImpl[] makeWinds(String[] files)
throws VisADException, RemoteException, IOException
{
DataImpl[] file_data = new DataImpl[n_stations];
FieldImpl[] time_field = new FieldImpl[n_stations];
double[][] time_offset = null;
double[] base_date = new double[n_stations];
double[] base_time = new double[n_stations];
Gridded1DSet d_set = null;
FlatField new_ff = null;
RealType alt;
RealType spd;
RealType dir;
RealType u_wind = RealType.getRealType("u_wind");
RealType v_wind = RealType.getRealType("v_wind");
//- create a new netcdf reader
Plain plain = new Plain();
//- retrieve file data objects
for ( int kk = 0; kk < n_stations; kk++) {
file_data[kk] = plain.open(files[kk]);
}
//- make sub mathtype for file objects
MathType file_type = file_data[0].getType();
System.out.println(file_type.prettyString());
System.out.println();
FunctionType f_type0 =
(FunctionType)((TupleType)file_type).getComponent(2);
TupleType ttype = (TupleType) f_type0.getRange();
int p_field_index = ttype.getDimension() - 1;
FunctionType f_type1 =
//- (FunctionType)((TupleType)f_type0.getRange()).getComponent(10);
//- (FunctionType)((TupleType)f_type0.getRange()).getComponent(12);
(FunctionType) ttype.getComponent(p_field_index);
RealTupleType rng_tuple = (RealTupleType) f_type1.getRange();
int altitude_index = rng_tuple.getIndex("Altitude");
//-altitude = (RealType)((RealTupleType)f_type1.getRange()).getComponent(0);
// altitude = (RealType)((RealTupleType)f_type1.getRange()).getComponent(1);
altitude = (RealType) rng_tuple.getComponent(altitude_index);
int windSpeed_index = rng_tuple.getIndex("windSpeed");
//-spd = (RealType)((RealTupleType)f_type1.getRange()).getComponent(4);
//-spd = (RealType)((RealTupleType)f_type1.getRange()).getComponent(5);
spd = (RealType) rng_tuple.getComponent(windSpeed_index);
int windDir_index = rng_tuple.getIndex("windDir");
//-dir = (RealType)((RealTupleType)f_type1.getRange()).getComponent(3);
//-dir = (RealType)((RealTupleType)f_type1.getRange()).getComponent(4);
dir = (RealType) rng_tuple.getComponent(windDir_index);
RealType[] r_types = { dir, spd };
/* WLH 28 Dec 99 */
RealType[] uv_types = { u_wind, v_wind };
// EarthVectorType uv = new EarthVectorType(uv_types); WLH meeds m/s
RealTupleType uv = new RealTupleType(uv_types);
CoordinateSystem cs = new WindPolarCoordinateSystem(uv);
RealTupleType ds = new RealTupleType(r_types, cs, null);
FunctionType alt_to_ds = new FunctionType(altitude, ds);
FunctionType alt_to_uv = new FunctionType(altitude, uv);
RealType domain_type = (RealType)
((TupleType)f_type0.getRange()).getComponent(0);
time = domain_type;
FunctionType new_type = new FunctionType(RealType.Time, alt_to_uv);
FieldImpl[] winds = new FieldImpl[n_stations];
for ( int ii = 0; ii < n_stations; ii++ )
{
base_date[ii] = (double)
((Real)((Tuple)file_data[ii]).getComponent(0)).getValue();
base_time[ii] = (double)
((Real)((Tuple)file_data[ii]).getComponent(1)).getValue();
time_field[ii] = (FieldImpl)
((Tuple)file_data[ii]).getComponent(2);
station_lat[ii] =
((Real)((Tuple)time_field[ii].getSample(0)).getComponent(6)).getValue();
station_lon[ii] =
-((Real)((Tuple)time_field[ii].getSample(0)).getComponent(7)).getValue();
station_alt[ii] =
((Real)((Tuple)time_field[ii].getSample(0)).getComponent(8)).getValue();
station_id[ii] =
((Real)((Tuple)time_field[ii].getSample(0)).getComponent(9)).getValue();
if (ii == 0) {
start_time = base_time[0];
start_date = (int) base_date[0];
}
/*
System.out.println("wind " + ii + " date: " + base_date[ii] +
" time: " + base_time[ii]);
wind 0 date: 1.9991226E7 time: 9.461664E8
wind 1 date: 1.9991226E7 time: 9.461664E8
wind 2 date: 1.9991226E7 time: 9.461664E8
wind 3 date: 1.9991226E7 time: 9.461664E8
wind 4 date: 1.9991226E7 time: 9.461664E8
looks like 19991226 and seconds since 1-1-70
time_offset looks like seconds since 0Z
*/
int length = time_field[ii].getLength();
time_offset = new double[1][length];
FlatField[] range_data = new FlatField[length];
double[][] samples = null; // WLH
for ( int jj = 0; jj < length; jj++ )
{
Tuple range = (Tuple) time_field[ii].getSample(jj);
time_offset[0][jj] = (double)((Real)range.getComponent(0)).getValue();
//-FlatField p_field = (FlatField) range.getComponent(10);
//-FlatField p_field = (FlatField) range.getComponent(12);
FlatField p_field = (FlatField) range.getComponent(p_field_index);
double[][] values =
p_field.getValues(); // WLH - (alt, ?, ?, dir, spd, ???)
double[][] new_values = new double[2][values[0].length];
if ( jj == 0 ) //- only once, vertical range gates don't change
{
samples = new double[1][values[0].length]; // WLH
//-System.arraycopy(values[0], 0, samples[0], 0, samples[0].length);
//-System.arraycopy(values[1], 0, samples[0], 0, samples[0].length);
System.arraycopy(values[altitude_index], 0, samples[0], 0, samples[0].length);
d_set = new Gridded1DSet(altitude, Set.doubleToFloat(samples), samples[0].length);
}
new_ff = new FlatField(alt_to_uv, d_set);
/* WLH - fill in missing winds - this also extrapolates to missing
start or end altitudes - but it does nothing if all winds are missing */
int n_not_miss = 0;
int[] not_miss = new int[values[0].length];
for ( int mm = 0; mm < values[0].length; mm++ )
{
//-if ( values[3][mm] <= -9999 ) {
//-if ( values[4][mm] <= -9999 ) {
if ( values[windDir_index][mm] <= -9999 ) {
new_values[0][mm] = Float.NaN;
}
else {
//-new_values[0][mm] = values[3][mm];
//-new_values[0][mm] = values[4][mm];
new_values[0][mm] = values[windDir_index][mm];
}
//-if ( values[4][mm] <= -9999 ) {
//-if ( values[5][mm] <= -9999 ) {
if ( values[windSpeed_index][mm] <= -9999 ) {
new_values[1][mm] = Float.NaN;
}
else {
//-new_values[1][mm] = values[4][mm];
//-new_values[1][mm] = values[5][mm];
new_values[1][mm] = values[windSpeed_index][mm];
}
if (new_values[0][mm] == new_values[0][mm] &&
new_values[1][mm] == new_values[1][mm]) {
not_miss[n_not_miss] = mm;
n_not_miss++;
}
}
if (0 < n_not_miss && n_not_miss < values[0].length) {
int nn = n_not_miss;
if (not_miss[0] > 0) nn += not_miss[0];
int endlen = values[0].length - (not_miss[n_not_miss-1]+1);
if (endlen > 0) nn += endlen;
float[][] newer_values = new float[2][nn];
float[][] newer_samples = new float[1][nn];
// fill in non-missing values
for (int i=0; i (lon,lat,alt) -> (T,TD,WV,AGE)
//
advect_field = new FieldImpl(advect_field_type, rtvls.getDomainSet());
//- resample winds domain (time) to rtvls
//
rtvls_domain = rtvls.getDomainSet();
wind_to_rtvl_time = (FieldImpl)
winds.resample( rtvls_domain,
Data.WEIGHTED_AVERAGE,
Data.NO_ERRORS );
//- resample rtvls domain (altitude) to winds at each rtvl time
//
int len = rtvls.getLength();
rtvl_on_wind = new FlatField[len];
wind_on_wind = new FieldImpl[len];
for ( int tt = 0; tt < len; tt++ ) {
alt_to_rtvl = (FieldImpl) rtvls.getSample(tt);
alt_to_wind = (FieldImpl) wind_to_rtvl_time.getSample(tt);
Set ds = alt_to_wind.getDomainSet();
// WLH height limit
float[][] samples = ds.getSamples();
float[] ns = new float[samples[0].length];
int nn = 0;
for (int i=0; i -50.) {
retval = ( coef[0] + temp*(coef[1] + temp*(coef[2] + temp*(coef[3] +
temp*(coef[4] + temp*(coef[5] + temp*(coef[6] + temp*coef[7])))))) );
}
else {
double tt = (-temp - 50.)/5.;
int inx = (int) tt;
if (inx < escold.length) {
retval = escold[inx] + (tt % 1.)*(escold[inx+1]-escold[inx]);
} else {
retval = 1e-7;
}
}
return retval;
}
/** mixing ratio
*
*/
public static double mixingRatio(double t, double p) {
double e = satVapPres(t);
return ( 621.97*e/(p - e) );
}
/** relative humidity
*
*/
public static double relativeHumidity(double t, double td) {
return (satVapPres(td) / satVapPres(t));
}
public static double potentialTemperature( double t, double p )
{
double R_Cp = 0.28585;
double Ps = 1000; //- reference pressure, (mb)
return t*Math.pow((Ps/p), R_Cp);
}
public static double equivPotentialTemperature(double theta,
double temp,
double press )
{
double Lc = 2.5*1000000.0;
double Cp = 1004.0;
double thetaE;
double Qs;
Qs = mixingRatio(temp, press*100);
Qs = Qs/1000.0;
thetaE = theta*Math.exp((Lc*Qs)/(Cp*temp));
return thetaE;
}
public static double equivPotentialTemperatureStar( double theta,
double Q,
double temp )
{
double Lc = 2.5*1000000.0;
double Cp = 1004.0;
Q = Q/1000.0;
return theta*Math.exp((Lc*Q)/(Cp*temp));
}
}
Ads help maintain this website.