From 432f0ec253b7a238f7dbc64125b2591351d0b774 Mon Sep 17 00:00:00 2001 From: Stephen Gilbert Date: Mon, 11 Aug 2014 15:47:57 -0400 Subject: [PATCH] VLab Issue #4001 - NCEP EDEX and EDEX Common delivery for 14.2.1-n GRIB config, TCM fix, and PWAT calculation for soundings Change-Id: Ic46db6f57da1446de27693ef3d00c664af6a7431 Former-commit-id: dc8043bf03c21143497f3a766e49e2816bae5b50 [formerly 327f39109e95f301552922c9051e8b6390edb112] [formerly af9384d8d77d8e1a8681397e55495b29decf7fc6 [formerly 598d22b0c943c5de9fc9ab3a56cde717c374fdfe]] Former-commit-id: af9384d8d77d8e1a8681397e55495b29decf7fc6 Former-commit-id: de62c1fa889ac4f8698faa9f082df81c91f8e8d8 --- .../base/grib/grids/grid17991059001.xml | 37 + .../base/grib/models/gribModels_NCEP-7.xml | 10 + .../base/parameter/alias/gempak.xml | 3 + .../geomag/calculation/CalcUtil.java | 6 +- .../common/sounding/NcSoundingProfile.java | 317 ++--- .../edex/common/sounding/NcSoundingTools.java | 177 +++ .../res/pointdata/ncpafmdb.xml | 2 + .../ncep/edex/plugin/tcm/util/TcmParser.java | 1217 +++++++++-------- .../uengine/tasks/profile/NcSoundingDrv.java | 107 +- .../base/python/NcSoundingDataRequest.py | 13 + 10 files changed, 1116 insertions(+), 773 deletions(-) create mode 100644 edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/grids/grid17991059001.xml create mode 100644 ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingTools.java diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/grids/grid17991059001.xml b/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/grids/grid17991059001.xml new file mode 100644 index 0000000000..35d648e6a0 --- /dev/null +++ b/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/grids/grid17991059001.xml @@ -0,0 +1,37 @@ + + + + 17991059001 + 3 km LCC limited domain CONUS grid (used by HRRR) + 21.138 + -122.72 + LowerLeft + 1799 + 1059 + 3.0 + 3.0 + km + 6371229.0 + 6371229.0 + -97.5 + 38.5 + 38.5 + diff --git a/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/models/gribModels_NCEP-7.xml b/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/models/gribModels_NCEP-7.xml index bb3547d1f0..95edaaccc5 100644 --- a/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/models/gribModels_NCEP-7.xml +++ b/edexOsgi/com.raytheon.edex.plugin.grib/utility/edex_static/base/grib/models/gribModels_NCEP-7.xml @@ -1094,6 +1094,16 @@ + + hrrr +
7
+ 0 + 17991059001 + + 83 + +
+ RTMA
7
diff --git a/edexOsgi/com.raytheon.uf.common.parameter/utility/common_static/base/parameter/alias/gempak.xml b/edexOsgi/com.raytheon.uf.common.parameter/utility/common_static/base/parameter/alias/gempak.xml index 9a94affdc5..230f404f2a 100644 --- a/edexOsgi/com.raytheon.uf.common.parameter/utility/common_static/base/parameter/alias/gempak.xml +++ b/edexOsgi/com.raytheon.uf.common.parameter/utility/common_static/base/parameter/alias/gempak.xml @@ -211,6 +211,7 @@ CLDM MIXR MMSL + TKMN06 TMNK TMNK01 TMNK03 @@ -220,6 +221,7 @@ TMNK18 TMNK24 TMNK48 + TKMX06 TMXK TMXK01 TMXK03 @@ -303,6 +305,7 @@ TCLD18 TCLD24 TCLD48 + TCWTR TSTM TOZO APCP diff --git a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/calculation/CalcUtil.java b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/calculation/CalcUtil.java index d31e20738c..3028d96a35 100644 --- a/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/calculation/CalcUtil.java +++ b/ncep/gov.noaa.nws.ncep.common.dataplugin.geomag/src/gov/noaa/nws/ncep/common/dataplugin/geomag/calculation/CalcUtil.java @@ -23,6 +23,7 @@ import java.util.Map; * ----------- ---------- ---------- -------------------------- * 05/14/2013 #989 qzhou Initial Creation * 06/23/2014 R4152 qzhou Touched up 3 functions + * 07/22/2014 R4152 qzhou Fixed getMedian. This func. is uesd very rare if ever * * * @author qzhou @@ -534,11 +535,10 @@ public class CalcUtil { // remove missing data List newArray = new ArrayList(); - for (int k = 0; k < arraySort.length - 1; k++) + for (int k = 0; k < arraySort.length; k++) { if (arraySort[k] != MISSING_VAL) newArray.add(arraySort[k]); - else - break; // to sorted arraySort + } int size = newArray.size(); if (size % 2 == 0) diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingProfile.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingProfile.java index 2a6eb3b00b..519ee7959a 100644 --- a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingProfile.java +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingProfile.java @@ -1,4 +1,5 @@ package gov.noaa.nws.ncep.edex.common.sounding; + /** * * gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile @@ -18,13 +19,13 @@ package gov.noaa.nws.ncep.edex.common.sounding; * 09/14/2011 457 S. Gurung Renamed ObsSndType.H5UAIR to ObsSndType.NCUAIR *10/06/2011 465 Archana Added a list of NcSoundingLayer2 objects to the sounding profile * 02/15/2012 Chin Chen added fcsTime to support pfc sounding query + * 07/23/2014 Chin Chen Support PW * * * @author Chin Chen * @version 1.0 */ -import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -35,220 +36,226 @@ import javax.xml.bind.annotation.XmlRootElement; import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + @XmlRootElement @XmlAccessorType(XmlAccessType.NONE) @DynamicSerialize -public class NcSoundingProfile implements ISerializableObject{ - /** +public class NcSoundingProfile implements ISerializableObject { + /** * */ - private static final long serialVersionUID = 6858474095965608817L; + private static final long serialVersionUID = 6858474095965608817L; - @DynamicSerializeElement + @DynamicSerializeElement public static final float MISSING = -9999.f; - public static enum PfcSndType { + + public static enum PfcSndType { NAMSND, GFSSND, RUC2SND, RUCPTYPSND, BROWSE, NONE }; + public static enum MdlSndType { - ANY, NONE + ANY, NONE }; - public static enum ObsSndType { - NCUAIR, UAIR, DROP, TAMDAR, BUFRUA //same as uair but using bufrua decoder and data is saved in HDF5 - ,BROWSE, NONE + + public static enum ObsSndType { + NCUAIR, UAIR, DROP, TAMDAR, BUFRUA // same as uair but using bufrua + // decoder and data is saved in HDF5 + , BROWSE, NONE }; - //Important Note: - //Chin: definition is based on UAIR record. stnid is string of character, stnnum is string of number - //BUFRUA has different definition. stnid is string of number which is stnnum in UAIR, - //and stnname is string of character which is stnid in UAIR.. - //type conversion is done at BUFRUA code. + + // Important Note: + // Chin: definition is based on UAIR record. stnid is string of character, + // stnnum is string of number + // BUFRUA has different definition. stnid is string of number which is + // stnnum in UAIR, + // and stnname is string of character which is stnid in UAIR.. + // type conversion is done at BUFRUA code. public static enum SndQueryKeyType { - LATLON, STNID, STNNUM, NONE + LATLON, STNID, STNNUM, NONE }; + @DynamicSerializeElement private List soundingLyLst; @DynamicSerializeElement private List soundingLyLst2; - - @DynamicSerializeElement + + @DynamicSerializeElement private float stationElevation; - //@DynamicSerializeElement - //private String stationId; + + // @DynamicSerializeElement + // private String stationId; @DynamicSerializeElement - private double stationLatitude; + private double stationLatitude; + @DynamicSerializeElement - private double stationLongitude; + private double stationLongitude; + @DynamicSerializeElement private float sfcPress; - + @DynamicSerializeElement private String stationId; @DynamicSerializeElement private int stationNum; - + @DynamicSerializeElement private long fcsTime; @DynamicSerializeElement private NcSoundingCube.QueryStatus rtnStatus = NcSoundingCube.QueryStatus.OK; - - public NcSoundingCube.QueryStatus getRtnStatus() { - return rtnStatus; - } + // Support PW + @DynamicSerializeElement + private float pw = -1; - public void setRtnStatus(NcSoundingCube.QueryStatus rtnStatus) { - this.rtnStatus = rtnStatus; - } + public NcSoundingCube.QueryStatus getRtnStatus() { + return rtnStatus; + } - public String getStationId() { - return stationId; - } + public void setRtnStatus(NcSoundingCube.QueryStatus rtnStatus) { + this.rtnStatus = rtnStatus; + } - public void setStationId(String stnId) { - this.stationId = stnId; - } + public String getStationId() { + return stationId; + } - public int getStationNum() { - return stationNum; - } + public void setStationId(String stnId) { + this.stationId = stnId; + } - public void setStationNum(int stnNum) { - this.stationNum = stnNum; - } + public int getStationNum() { + return stationNum; + } - - public long getFcsTime() { - return fcsTime; - } + public void setStationNum(int stnNum) { + this.stationNum = stnNum; + } - public void setFcsTime(long fcsTime) { - this.fcsTime = fcsTime; - } + public long getFcsTime() { + return fcsTime; + } - public List getSoundingLyLst() { - return soundingLyLst; - } + public void setFcsTime(long fcsTime) { + this.fcsTime = fcsTime; + } - public void setSoundingLyLst(List soundingLyLst) { - this.soundingLyLst = soundingLyLst; - } + public List getSoundingLyLst() { + return soundingLyLst; + } + + public void setSoundingLyLst(List soundingLyLst) { + this.soundingLyLst = soundingLyLst; + } /** - * @return the soundingLyLst2 - */ - public List getSoundingLyLst2() { - return soundingLyLst2; - } + * @return the soundingLyLst2 + */ + public List getSoundingLyLst2() { + return soundingLyLst2; + } - /** - * @param soundingLyLst2 the soundingLyLst2 to set - */ - public void setSoundingLyLst2(List soundingLyLst2) { - this.soundingLyLst2 = soundingLyLst2; - } - - public float getStationElevation() { - return stationElevation; - } + /** + * @param soundingLyLst2 + * the soundingLyLst2 to set + */ + public void setSoundingLyLst2(List soundingLyLst2) { + this.soundingLyLst2 = soundingLyLst2; + } - public void setStationElevation(float stationElevation) { - this.stationElevation = stationElevation; - } + public float getStationElevation() { + return stationElevation; + } + public void setStationElevation(float stationElevation) { + this.stationElevation = stationElevation; + } - public double getStationLatitude() { - return stationLatitude; - } + public double getStationLatitude() { + return stationLatitude; + } - public void setStationLatitude(double stationLatitude) { - this.stationLatitude = stationLatitude; - } + public void setStationLatitude(double stationLatitude) { + this.stationLatitude = stationLatitude; + } - public double getStationLongitude() { - return stationLongitude; - } + public double getStationLongitude() { + return stationLongitude; + } - public void setStationLongitude(double stationLongitude) { - this.stationLongitude = stationLongitude; - } + public void setStationLongitude(double stationLongitude) { + this.stationLongitude = stationLongitude; + } - public float getSfcPress() { - return sfcPress; - } + public float getSfcPress() { + return sfcPress; + } - public void setSfcPress(float sfcPress) { - this.sfcPress = sfcPress; - } + public void setSfcPress(float sfcPress) { + this.sfcPress = sfcPress; + } - public static long getSerialVersionUID() { - return serialVersionUID; - } + public static long getSerialVersionUID() { + return serialVersionUID; + } - // TO-DO: Add station number (stationNumber) - public NcSoundingProfile(List soundingLyLst2, - List soundingLyLst, - float stationElevation, String stationId, float stationLatitude, - float stationLongitude, float sfcPress, int stnNum) { - super(); - this.soundingLyLst2 = soundingLyLst2; - this.soundingLyLst = soundingLyLst; - this.stationElevation = stationElevation; - this.stationId = stationId; - this.stationLatitude = stationLatitude; - this.stationLongitude = stationLongitude; - this.sfcPress = sfcPress; - this.stationNum = stnNum; - } + // TO-DO: Add station number (stationNumber) + public NcSoundingProfile(List soundingLyLst2, + List soundingLyLst, float stationElevation, + String stationId, float stationLatitude, float stationLongitude, + float sfcPress, int stnNum) { + super(); + this.soundingLyLst2 = soundingLyLst2; + this.soundingLyLst = soundingLyLst; + this.stationElevation = stationElevation; + this.stationId = stationId; + this.stationLatitude = stationLatitude; + this.stationLongitude = stationLongitude; + this.sfcPress = sfcPress; + this.stationNum = stnNum; + } - public NcSoundingProfile() { - super(); - this.soundingLyLst = new ArrayList(); - this.soundingLyLst2 = new ArrayList(); - this.stationElevation = MISSING; - this.stationId = ""; - this.stationLatitude = MISSING; - this.stationLongitude = MISSING; - this.sfcPress = MISSING; - this.stationNum= 0; - } + public NcSoundingProfile() { + super(); + this.soundingLyLst = new ArrayList(); + this.soundingLyLst2 = new ArrayList(); + this.stationElevation = MISSING; + this.stationId = ""; + this.stationLatitude = MISSING; + this.stationLongitude = MISSING; + this.sfcPress = MISSING; + this.stationNum = 0; + } - /* - @Override - protected AbstractStorageRecord cloneInternal() { - // TODO Auto-generated method stub - System.out.println("NcSoundingProfile cloneInternal()"); - return null; - } + public float getPw() { + return pw; + } - @Override - public Object getDataObject() { - // TODO Auto-generated method stub - System.out.println("NcSoundingProfile getDataObject()"); - return null; - } + public void setPw(float pw) { + this.pw = pw; + } - @Override - public int getSizeInBytes() { - // TODO Auto-generated method stub - System.out.println("NcSoundingProfile getSizeInBytes()"); - return 0; - } + /* + * @Override protected AbstractStorageRecord cloneInternal() { // TODO + * Auto-generated method stub + * System.out.println("NcSoundingProfile cloneInternal()"); return null; } + * + * @Override public Object getDataObject() { // TODO Auto-generated method + * stub System.out.println("NcSoundingProfile getDataObject()"); return + * null; } + * + * @Override public int getSizeInBytes() { // TODO Auto-generated method + * stub System.out.println("NcSoundingProfile getSizeInBytes()"); return 0; + * } + * + * @Override public void reduce(int[] indices) { // TODO Auto-generated + * method stub System.out.println("NcSoundingProfile ()"); } + * + * @Override public boolean validateDataSet() { // TODO Auto-generated + * method stub System.out.println("NcSoundingProfile validateDataSet()"); + * return false; } + */ - @Override - public void reduce(int[] indices) { - // TODO Auto-generated method stub - System.out.println("NcSoundingProfile ()"); - } - - @Override - public boolean validateDataSet() { - // TODO Auto-generated method stub - System.out.println("NcSoundingProfile validateDataSet()"); - return false; - } - */ - } - diff --git a/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingTools.java b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingTools.java new file mode 100644 index 0000000000..b93998ce0d --- /dev/null +++ b/ncep/gov.noaa.nws.ncep.edex.common/src/gov/noaa/nws/ncep/edex/common/sounding/NcSoundingTools.java @@ -0,0 +1,177 @@ +package gov.noaa.nws.ncep.edex.common.sounding; + +import java.util.List; + +/** + * + * gov.noaa.nws.ncep.edex.common.sounding.NcSoundingTools + * + * This code has been developed by the SIB for use in the AWIPS2 system. + * + *
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#     Engineer    Description
+ * -------      -------     --------    -----------
+ * 07/24/2014               Chin Chen   Initial coding 
+ *                                      Support PW computation
+ * 
+ * 
+ * 
+ * + * @author Chin Chen + * @version 1.0 + */ +public class NcSoundingTools { + + /************************************************************* + * PRECIP_WATER Calculates the Precipitation Water in mm from Bottom level + * of layer (mb) to Top level of layer (mb) + *************************************************************/ + public static float precip_water(List sndlayers) { + float pw = 0; + float d1, p1, d2, p2, tot, w1, w2, wbar; + + // ----- Start with interpolated bottom layer ----- + // find surface layer or first layer with valid dewpoint + int sfcIndex = 0; + for (int i = 0; i < sndlayers.size(); i++) { + if (sndlayers.get(i).getDewpoint() != -9999f) { + sfcIndex = i; + break; + } + } + d1 = sndlayers.get(sfcIndex).getDewpoint(); // dewp + // in + // C + p1 = sndlayers.get(sfcIndex).getPressure(); // pressure + // n + // mb + + tot = 0; + for (int i = sfcIndex + 1; i < sndlayers.size(); i++) { + /* ----- Calculate every level that reports a dwpt ----- */ + d2 = sndlayers.get(i).getDewpoint(); // dewp + // in C + if (d2 == -9999f) + continue; + p2 = sndlayers.get(i).getPressure(); // pressure + // n mb + w1 = mixingRatio(d1, p1); + w2 = mixingRatio(d2, p2); + wbar = (w1 + w2) / 2; + tot = tot + wbar * (p1 - p2); + // System.out.println("p1=" + p1 + " d1=" + d1 + " p2=" + p2 + + // " d2=" + // + d2); + d1 = d2; + p1 = p2; + // test the case when top level is 400 mb + // if (p2 == 400) + // break; + } + + /* ----- Convert to mm (from g*mb/kg) ----- */ + pw = tot * 0.00040173f * 25.4f; + + return pw; + } + + public static float precip_water2(List sndlayers) { + float pw = 0; + float d1, p1, d2, p2, tot, w1, w2, wbar; + // ----- Start with interpolated bottom layer ----- + // find surface layer or first layer with valid dewpoint + int sfcIndex = 0; + for (int i = 0; i < sndlayers.size(); i++) { + if (sndlayers.get(i).getDewpoint().getValue().floatValue() != -9999f) { + sfcIndex = i; + break; + } + } + d1 = sndlayers.get(sfcIndex).getDewpoint().getValue().floatValue(); // dewp + // in + // C + p1 = sndlayers.get(sfcIndex).getPressure().getValue().floatValue(); // pressure + // n + // mb + + tot = 0; + for (int i = sfcIndex + 1; i < sndlayers.size(); i++) { + /* ----- Calculate every level that reports a dwpt ----- */ + d2 = sndlayers.get(i).getDewpoint().getValue().floatValue(); // dewp + // in C + if (d2 == -9999f) + continue; + p2 = sndlayers.get(i).getPressure().getValue().floatValue(); // pressure + // n mb + w1 = mixingRatio(d1, p1); + w2 = mixingRatio(d2, p2); + wbar = (w1 + w2) / 2; + tot = tot + wbar * (p1 - p2); + d1 = d2; + p1 = p2; + // test the case when top level is 400 mb + // if (p2 == 400) + // break; + } + + /* ----- Convert to mm (from g*mb/kg) ----- */ + pw = tot * 0.00040173f * 25.4f; + + return pw; + } + + /* + * Compute mixing ratio from DWPC and PRES. Chin: copy from + * gov.noaa.nws.ncep.edex.uengine.tasks.profile.MergeSounding + */ + private static float mixingRatio(float td, float pres) { + float vapr = vaporPressure(td); + + float corr = (1.001f + ((pres - 100.f) / 900.f) * .0034f); + + float e = corr * vapr; + if (e > (.5f * pres)) { + return -9999f; + } else { + return .62197f * (e / (pres - e)) * 1000.f; + } + } + + /* + * Compute vapor pressure from DWPC. Chin: copy from + * gov.noaa.nws.ncep.edex.uengine.tasks.profile.MergeSounding + */ + private static float vaporPressure(float td) { + return (6.112f * (float) Math.exp((17.67 * td) / (td + 243.5))); + } + + // The followings are converted from BigSharp, the computation results are + // about the same as above methods. + // private static float mixratio(float pres, float temp) + // + // { + // float x, wfw, fwesw; + // + // x = 0.02f * (temp - 12.5f + 7500.0f / pres); + // wfw = 1.0f + 0.0000045f * pres + 0.0014f * x * x; + // fwesw = wfw * vappres(temp); + // return 621.97f * (fwesw / (pres - fwesw)); + // } + // + // private static float vappres(float temp) + // + // { + // double pol; + // pol = temp * (1.1112018e-17 + temp * (-3.0994571e-20)); + // pol = temp * (2.1874425e-13 + temp * (-1.789232e-15 + pol)); + // pol = temp * (4.3884180e-09 + temp * (-2.988388e-11 + pol)); + // pol = temp * (7.8736169e-05 + temp * (-6.111796e-07 + pol)); + // pol = .99999683e-00 + temp * (-9.082695e-03 + pol); + // pol = (pol * pol); + // pol = (pol * pol); + // return (6.1078f / (float) (pol * pol)); + // } + +} diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/pointdata/ncpafmdb.xml b/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/pointdata/ncpafmdb.xml index cd502c3f09..e3b6e176d4 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/pointdata/ncpafmdb.xml +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.ncpafm/res/pointdata/ncpafmdb.xml @@ -4,6 +4,7 @@ * Date Ticket# Engineer Description * __________ _______ __________ __________________________ * 10/12/2011 126 G. Hull Initial Creation + * 07/30/2014 B. Hebbard Add refTime parameter --> @@ -13,4 +14,5 @@ + \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/src/gov/noaa/nws/ncep/edex/plugin/tcm/util/TcmParser.java b/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/src/gov/noaa/nws/ncep/edex/plugin/tcm/util/TcmParser.java index b0e26ed2a1..8a9003697d 100644 --- a/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/src/gov/noaa/nws/ncep/edex/plugin/tcm/util/TcmParser.java +++ b/ncep/gov.noaa.nws.ncep.edex.plugin.tcm/src/gov/noaa/nws/ncep/edex/plugin/tcm/util/TcmParser.java @@ -12,6 +12,7 @@ * 06/2009 128 T. Lee Creation * 07/2009 128 T. Lee Migrated to TO11 * 06/2010 128 T. Lee Migrated to TO11DR11 + * 07/2014 T. Lee Enhanced DM for Atlantic Basin * * * @author T.Lee @@ -20,193 +21,205 @@ package gov.noaa.nws.ncep.edex.plugin.tcm.util; -import gov.noaa.nws.ncep.common.dataplugin.tcm.TcmRecord; import gov.noaa.nws.ncep.common.dataplugin.tcm.TcmPositionWinds; +import gov.noaa.nws.ncep.common.dataplugin.tcm.TcmRecord; +import gov.noaa.nws.ncep.edex.util.UtilN; + import java.util.Calendar; import java.util.Scanner; import java.util.regex.MatchResult; import java.util.regex.Matcher; import java.util.regex.Pattern; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import com.raytheon.uf.edex.wmo.message.WMOHeader; -import com.raytheon.uf.common.time.DataTime; -import gov.noaa.nws.ncep.edex.util.UtilN; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.edex.wmo.message.WMOHeader; public class TcmParser { - private static Scanner sc = null; + private static Scanner sc = null; + private final Log logger = LogFactory.getLog(getClass()); - int basin; - static MatchResult result; + + int basin; + + static MatchResult result; + boolean forecast; + Calendar save_time = null; - String TPC = "MIAMI FL\\s+(AL|EP)(\\d{2})(\\d{4})"; - String CPHC = "HONOLULU HI\\s+(EP|CP)(\\d{2})(\\d{4})"; - + + String TPC = "MIAMI FL\\s+(AL|EP)(\\d{2})(\\d{4})"; + + String CPHC = "HONOLULU HI\\s+(EP|CP)(\\d{2})(\\d{4})"; + /** * Default constructor - */ + */ public TcmParser() { } /** * Decode TCM report * - * @param bull the bulletin message + * @param bull + * the bulletin message * @param record */ - public void processTcm (String bull, TcmRecord record) { - int basin; - forecast = false; - String bull_partA, bull_partB; + public void processTcm(String bull, TcmRecord record) { + int basin; + forecast = false; + String bull_partA, bull_partB; - /* - * JTWC headers. - */ - String JTWC = "NAVMARFCSTCEN PEARL HARBOR HI/JTWC"; - String jtwc_header = "[A-Z]{4}\\d{0,2} PGTW (\\d{6})\r\r\n"; - Pattern pt_jtwc = Pattern.compile(jtwc_header); - Matcher mt_jtwc = pt_jtwc.matcher(bull); - - /* - * TPC header. - */ - Pattern pt_tpc = Pattern.compile (TPC); - Matcher mt_tpc = pt_tpc.matcher(bull); - - /* - * Central Pacific header. - */ - Pattern pt_cphc = Pattern.compile (CPHC); - Matcher mt_cphc = pt_cphc.matcher(bull); + /* + * JTWC headers. + */ + String JTWC = "NAVMARFCSTCEN PEARL HARBOR HI/JTWC"; + String jtwc_header = "[A-Z]{4}\\d{0,2} PGTW (\\d{6})\r\r\n"; + Pattern pt_jtwc = Pattern.compile(jtwc_header); + Matcher mt_jtwc = pt_jtwc.matcher(bull); - try { - if (bull.contains(JTWC) || mt_jtwc.find()) { - bull_partA = bull.substring(0,bull.indexOf("FORECASTS:")); - bull_partB = bull.substring(bull.indexOf("FORECASTS:"),bull.length()); - sc = new Scanner(bull_partA); - basin = 2; - } else { - try { - bull_partA = bull.substring(0,bull.indexOf("FORECAST VALID")); - bull_partB = bull.substring(bull.indexOf("FORECAST VALID"),bull.length()); - sc = new Scanner(bull_partA); - } catch (Exception e){ - bull_partA = bull; - bull_partB = null; - sc = new Scanner(bull); - } - if (mt_tpc.find()) { - basin = 1; - } else if (mt_cphc.find()) { - basin = 1; - } else { - throw new Exception (" Could not find forecast center!!"); - } - } + /* + * TPC header. + */ + Pattern pt_tpc = Pattern.compile(TPC); + Matcher mt_tpc = pt_tpc.matcher(bull); - /* - * Find and decode storm ID, name and advisory number. - */ - processStormAttr(basin,record); + /* + * Central Pacific header. + */ + Pattern pt_cphc = Pattern.compile(CPHC); + Matcher mt_cphc = pt_cphc.matcher(bull); - /* - * Find and set correction. - */ - processCorr(basin, record, bull); + try { + if (bull.contains(JTWC) || mt_jtwc.find()) { + bull_partA = bull.substring(0, bull.indexOf("FORECASTS:")); + bull_partB = bull.substring(bull.indexOf("FORECASTS:"), + bull.length()); + sc = new Scanner(bull_partA); + basin = 2; + } else { + try { + bull_partA = bull.substring(0, + bull.indexOf("FORECAST VALID")); + bull_partB = bull.substring(bull.indexOf("FORECAST VALID"), + bull.length()); + sc = new Scanner(bull_partA); + } catch (Exception e) { + bull_partA = bull; + bull_partB = null; + sc = new Scanner(bull); + } + if (mt_tpc.find()) { + basin = 1; + } else if (mt_cphc.find()) { + basin = 1; + } else { + throw new Exception(" Could not find forecast center!!"); + } + } - /* - * New TcmPositionWind record to hold current values - */ - TcmPositionWinds current = new TcmPositionWinds(); - Calendar cal=null; - if (basin == 2) { - cal = (Calendar)record.getIssueTime().clone(); - processLocationTime(basin,current,record,cal); - } - - /* - * Find and decode position accuracy. - */ - if (basin == 1) { - processPositionAccuracy(record); - } + /* + * Find and decode storm ID, name and advisory number. + */ + processStormAttr(basin, record); - /* - * Find and decode storm motion. - */ - processStormMotion(basin,forecast,current); + /* + * Find and set correction. + */ + processCorr(basin, record, bull); - /* - * Find and decode position accuracy. - */ - if (basin==2) { - processPositionAccuracy(record); - } + /* + * New TcmPositionWind record to hold current values + */ + TcmPositionWinds current = new TcmPositionWinds(); + Calendar cal = null; + if (basin == 2) { + cal = (Calendar) record.getIssueTime().clone(); + processLocationTime(basin, current, record, cal); + } - /* - * Find and decode minimum central pressure and eye size. - */ - if (basin == 1) { - processCentralPressure(record); - processEyeSize(record); - } + /* + * Find and decode position accuracy. + */ + if (basin == 1) { + processPositionAccuracy(record); + } - /* - * Find and decode current wind speed and gusts. - */ - processMaxWind(basin,forecast,current); + /* + * Find and decode storm motion. + */ + processStormMotion(basin, forecast, current); - /* - * Find and decode current 64 knot wind radii. - */ - processRadii64(basin,forecast,current); + /* + * Find and decode position accuracy. + */ + if (basin == 2) { + processPositionAccuracy(record); + } - /* - * Find and decode current 50 knot wind radii. - */ - processRadii50(basin,forecast,current); + /* + * Find and decode minimum central pressure and eye size. + */ + if (basin == 1) { + processCentralPressure(record); + processEyeSize(record); + } - /* - * Find and decode current 34 knot wind radii. - */ - processRadii34(basin,forecast,current); + /* + * Find and decode current wind speed and gusts. + */ + processMaxWind(basin, forecast, current); - /* - * Find and decode 12-ft seas. - */ - if (basin == 1) { - processWaveHeights(record); - } + /* + * Find and decode current 64 knot wind radii. + */ + processRadii64(basin, forecast, current); - /* - * Find and decode storm location - */ - if (basin == 1) { - cal = (Calendar)record.getIssueTime().clone(); - processLocationTime(basin,current,record,cal); - } - record.addPosWinds(current); + /* + * Find and decode current 50 knot wind radii. + */ + processRadii50(basin, forecast, current); - /* - * Set past center location if exists. - */ - if (basin == 1) { - TcmPositionWinds past = new TcmPositionWinds(); - cal = (Calendar)record.getIssueTime().clone(); - processLocationTime(past,record,cal); - record.addPosWinds(past); - } + /* + * Find and decode current 34 knot wind radii. + */ + processRadii34(basin, forecast, current); - /* - * Decode forecast message. - */ - processTcmForecasts(basin,bull_partB,record); - } - catch (Exception e) { - logger.info("Error in parsing TCM !!"); - } + /* + * Find and decode 12-ft seas. + */ + if (basin == 1) { + processWaveHeights(record); + } + + /* + * Find and decode storm location + */ + if (basin == 1) { + cal = (Calendar) record.getIssueTime().clone(); + processLocationTime(basin, current, record, cal); + } + record.addPosWinds(current); + + /* + * Set past center location if exists. + */ + if (basin == 1) { + TcmPositionWinds past = new TcmPositionWinds(); + cal = (Calendar) record.getIssueTime().clone(); + processLocationTime(past, record, cal); + record.addPosWinds(past); + } + + /* + * Decode forecast message. + */ + processTcmForecasts(basin, bull_partB, record); + } catch (Exception e) { + logger.info("Error in parsing TCM !!"); + } } /** @@ -217,101 +230,98 @@ public class TcmParser { * @param mndTime */ public void processWMO(byte[] wmohd, TcmRecord record, Calendar mndTime) { - WMOHeader hd = new WMOHeader (wmohd); - Calendar issueTime = UtilN.findDataTime(hd.getYYGGgg(),mndTime); - DataTime dt = new DataTime (issueTime); - if (wmohd != null) { - record.setIssueTime(issueTime); - record.setDataTime(dt); - } + WMOHeader hd = new WMOHeader(wmohd); + Calendar issueTime = UtilN.findDataTime(hd.getYYGGgg(), mndTime); + DataTime dt = new DataTime(issueTime); + if (wmohd != null) { + record.setIssueTime(issueTime); + record.setDataTime(dt); + } } - + /** * Process storm motion * - * @param ocean basin + * @param ocean + * basin * @param TcmPositionWinds */ public void processStormAttr(int basin, TcmRecord record) { - - /* - * Storm attributes expression. - */ - String HU = "HURRICANE (\\w+) FORECAST/ADVISORY NUMBER\\s+(\\w+)"; - String SUPER_TY = "SUPER TYPHOON (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; - String TY = "TYPHOON (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; - String TS = "TROPICAL STORM (\\w+) FORECAST/ADVISORY NUMBER\\s+(\\w+)"; - String TS_WP = "TROPICAL STORM (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; - String TC = "TROPICAL CYCLONE (\\w+) FORECAST/ADVISORY NUMBER\\s+(\\w+)"; - String TC_WP = "TROPICAL CYCLONE (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; - String TD = "TROPICAL DEPRESSION (\\S+) FORECAST/ADVISORY NUMBER\\s+(\\w+)"; - String TD_WP = "TROPICAL DEPRESSION (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; - String TD_SP = "TROPICAL DEPRESSION (\\S+) SPECIAL FORECAST/ADVISORY NUMBER\\s+(\\w+)"; - /* - * Find and set storm type, name and advisory from message - * - * Atlantic/Central Pacific scenarios - */ - try { - if (sc.findWithinHorizon(HU,0) != null) { - record.setStormType ("HURRICANE"); - } - else if (sc.findWithinHorizon(TS,0) != null) { - record.setStormType ("TROPICAL STORM"); - } - else if (sc.findWithinHorizon(TC,0) != null) { - record.setStormType ("TROPICAL CYCLONE"); - } - else if (sc.findWithinHorizon(TD,0) != null) { - record.setStormType ("TROPICAL DEPRESSION"); - } - else if (sc.findWithinHorizon(TD_SP,0) != null) { - record.setStormType ("TROPICAL DEPRESSION SPECIAL"); + /* + * Storm attributes expression. + */ + String HU = "HURRICANE (\\w+) FORECAST/ADVISORY NUMBER\\s+(\\w+)"; + String SUPER_TY = "SUPER TYPHOON (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; + String TY = "TYPHOON (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; + String TS = "TROPICAL STORM (\\w+) FORECAST/ADVISORY NUMBER\\s+(\\w+)"; + String TS_WP = "TROPICAL STORM (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; + String TC = "TROPICAL CYCLONE (\\w+) FORECAST/ADVISORY NUMBER\\s+(\\w+)"; + String TC_WP = "TROPICAL CYCLONE (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; + String TD = "TROPICAL DEPRESSION (\\S+) FORECAST/ADVISORY NUMBER\\s+(\\w+)"; + String TD_WP = "TROPICAL DEPRESSION (\\w+) \\((\\w+)\\) WARNING NR (\\d+)"; + String TD_SP = "TROPICAL DEPRESSION (\\S+) SPECIAL FORECAST/ADVISORY NUMBER\\s+(\\w+)"; - /* - * NW Pacific scenarios - */ - } else if (sc.findWithinHorizon(SUPER_TY,0) != null) { - record.setStormType ("SUPER TYPHOON"); - } else if (sc.findWithinHorizon(TY,0) != null) { - record.setStormType ("TYPHOON"); - } else if (sc.findWithinHorizon(TC_WP,0) != null) { - record.setStormType ("TROPICAL CYCLONE"); - } else if (sc.findWithinHorizon(TS_WP,0) != null) { - record.setStormType ("TROPICAL STORM"); - } else if (sc.findWithinHorizon(TD_WP,0) != null) { - record.setStormType ("TROPICAL DEPRESSION"); - } else { - throw new Exception("Could not find storm attributes!"); - } - } catch (Exception e) { - logger.info("Cannot find storm attributes"); - } + /* + * Find and set storm type, name and advisory from message + * + * Atlantic/Central Pacific scenarios + */ + try { + if (sc.findWithinHorizon(HU, 0) != null) { + record.setStormType("HURRICANE"); + } else if (sc.findWithinHorizon(TS, 0) != null) { + record.setStormType("TROPICAL STORM"); + } else if (sc.findWithinHorizon(TC, 0) != null) { + record.setStormType("TROPICAL CYCLONE"); + } else if (sc.findWithinHorizon(TD, 0) != null) { + record.setStormType("TROPICAL DEPRESSION"); + } else if (sc.findWithinHorizon(TD_SP, 0) != null) { + record.setStormType("TROPICAL DEPRESSION SPECIAL"); - result = sc.match(); - if (basin == 1) { - record.setStormName (result.group(1)); - record.setAdvisoryNumber (result.group(2)); - - /* - * Find and decode storm name and basin. - */ - if (sc.findWithinHorizon(TPC,0) != null || - sc.findWithinHorizon(CPHC,0) != null) { - result = sc.match(); - record.setBasin (result.group(1)); - record.setStormNumber (result.group(2)); - } + /* + * NW Pacific scenarios + */ + } else if (sc.findWithinHorizon(SUPER_TY, 0) != null) { + record.setStormType("SUPER TYPHOON"); + } else if (sc.findWithinHorizon(TY, 0) != null) { + record.setStormType("TYPHOON"); + } else if (sc.findWithinHorizon(TC_WP, 0) != null) { + record.setStormType("TROPICAL CYCLONE"); + } else if (sc.findWithinHorizon(TS_WP, 0) != null) { + record.setStormType("TROPICAL STORM"); + } else if (sc.findWithinHorizon(TD_WP, 0) != null) { + record.setStormType("TROPICAL DEPRESSION"); + } else { + throw new Exception("Could not find storm attributes!"); + } + } catch (Exception e) { + logger.info("Cannot find storm attributes"); + } - } else if (basin == 2) { - record.setStormNumber (result.group(1)); - record.setStormName (result.group(2)); - record.setAdvisoryNumber (result.group(3)); - record.setBasin ("WP"); - } + result = sc.match(); + if (basin == 1) { + record.setStormName(result.group(1)); + record.setAdvisoryNumber(result.group(2)); + + /* + * Find and decode storm name and basin. + */ + if (sc.findWithinHorizon(TPC, 0) != null + || sc.findWithinHorizon(CPHC, 0) != null) { + result = sc.match(); + record.setBasin(result.group(1)); + record.setStormNumber(result.group(2)); + } + + } else if (basin == 2) { + record.setStormNumber(result.group(1)); + record.setStormName(result.group(2)); + record.setAdvisoryNumber(result.group(3)); + record.setBasin("WP"); + } } - + /** * Process correction * @@ -320,47 +330,50 @@ public class TcmParser { * @param bulletin */ public void processCorr(int basin, TcmRecord record, String bulletin) { - if ( bulletin == null ) { - return; - } - if (basin == 1) { - if (bulletin.contains("...CORRECTED")) { - record.setCorr(true); - } else { - record.setCorr(false); - } - } else if ( basin == 2 ) { - if (bulletin.contains("CORRECTED//")) { - record.setCorr(true); - } else { - record.setCorr(false); - } - } + if (bulletin == null) { + return; + } + if (basin == 1) { + if (bulletin.contains("...CORRECTED")) { + record.setCorr(true); + } else { + record.setCorr(false); + } + } else if (basin == 2) { + if (bulletin.contains("CORRECTED//")) { + record.setCorr(true); + } else { + record.setCorr(false); + } + } } /** * Process storm motion * - * @param ocean basin - * @param forecast flag + * @param ocean + * basin + * @param forecast + * flag * @param TcmPositionWinds */ - public void processStormMotion(int basin, boolean forecast, TcmPositionWinds current) { - String DDSS = null; - if (basin == 1) { - DDSS = "PRESENT MOVEMENT TOWARD THE (\\w+) OR (\\d+) DEGREES AT\\s+(\\d+)\\s+KT"; - } else if (basin == 2) { - if (forecast) { - DDSS = "VECTOR TO (\\d+) HR POSIT: (\\d+) DEG/\\s+(\\d+)\\s+KT"; - } else { - DDSS = "MOVEMENT PAST (\\w+) HOURS - (\\d+)\\s+DEGREES AT\\s+(\\d+)\\s+KT"; - } - } - if (sc.findWithinHorizon(DDSS, 0) != null) { - result = sc.match(); - current.setStormDrct(Integer.parseInt(result.group(2))); - current.setStormSped(Integer.parseInt(result.group(3))); - } + public void processStormMotion(int basin, boolean forecast, + TcmPositionWinds current) { + String DDSS = null; + if (basin == 1) { + DDSS = "PRESENT MOVEMENT TOWARD THE (\\w+) OR (\\d+) DEGREES AT\\s+(\\d+)\\s+KT"; + } else if (basin == 2) { + if (forecast) { + DDSS = "VECTOR TO (\\d+) HR POSIT: (\\d+) DEG/\\s+(\\d+)\\s+KT"; + } else { + DDSS = "MOVEMENT PAST (\\w+) HOURS - (\\d+)\\s+DEGREES AT\\s+(\\d+)\\s+KT"; + } + } + if (sc.findWithinHorizon(DDSS, 0) != null) { + result = sc.match(); + current.setStormDrct(Integer.parseInt(result.group(2))); + current.setStormSped(Integer.parseInt(result.group(3))); + } } /** @@ -369,246 +382,261 @@ public class TcmParser { * @param TcmRecord */ public void processPositionAccuracy(TcmRecord record) { - String POSITION_ACCURACY = "POSITION ACCURATE TO WITHIN\\s+(\\d+)"; - if (sc.findWithinHorizon(POSITION_ACCURACY, 0) != null) { - result = sc.match(); - record.setPositionAccuracy(Integer.parseInt(result.group(1))); - } else { - POSITION_ACCURACY = "POSITION ACCURATE WITHIN\\s+(\\d+)"; - if (sc.findWithinHorizon(POSITION_ACCURACY, 0) != null) { - result = sc.match(); - record.setPositionAccuracy(Integer.parseInt(result.group(1))); - } - } + String POSITION_ACCURACY = "POSITION ACCURATE TO WITHIN\\s+(\\d+)"; + if (sc.findWithinHorizon(POSITION_ACCURACY, 0) != null) { + result = sc.match(); + record.setPositionAccuracy(Integer.parseInt(result.group(1))); + } else { + POSITION_ACCURACY = "POSITION ACCURATE WITHIN\\s+(\\d+)"; + if (sc.findWithinHorizon(POSITION_ACCURACY, 0) != null) { + result = sc.match(); + record.setPositionAccuracy(Integer.parseInt(result.group(1))); + } + } } - + /** * Process minimum central pressure * * @param TcmRecord */ public void processCentralPressure(TcmRecord record) { - String PMIN = "ESTIMATED MINIMUM CENTRAL PRESSURE\\s+(\\d+)\\sMB"; - if (sc.findWithinHorizon(PMIN, 0) != null) { - result = sc.match(); - record.setCentralPressure(Integer.parseInt(result.group(1))); - } + String PMIN = "ESTIMATED MINIMUM CENTRAL PRESSURE\\s+(\\d+)\\sMB"; + if (sc.findWithinHorizon(PMIN, 0) != null) { + result = sc.match(); + record.setCentralPressure(Integer.parseInt(result.group(1))); + } } - + /** * Process eye size * * @param TcmRecord */ public void processEyeSize(TcmRecord record) { - String EYE = "EYE DIAMETER\\s+(\\d+)\\s+"; - if (sc.findWithinHorizon(EYE, 0) != null) { - result = sc.match(); - record.setEyeSize(Integer.parseInt(result.group(1))); - } + String EYE = "EYE DIAMETER\\s+(\\d+)\\s+"; + if (sc.findWithinHorizon(EYE, 0) != null) { + result = sc.match(); + record.setEyeSize(Integer.parseInt(result.group(1))); + } } /** * Process current sustained winds and gusts * - * @param ocean basin + * @param ocean + * basin * @param TcmPositionWinds */ - public void processMaxWind(int basin, boolean forecast, TcmPositionWinds current) { - String wmax = null; - if (basin == 1) { - if (forecast) { - wmax = "MAX WIND\\s+(\\d+) KT...GUSTS\\s+(\\d+) KT"; - } else { - wmax = "SUSTAINED WINDS\\s+(\\d+) KT WITH GUSTS TO\\s+(\\d+) KT"; - } - } else if (basin == 2) { - wmax = "MAX SUSTAINED WINDS - (\\d+) KT, GUSTS\\s+(\\d+) KT"; - } - if (sc.findWithinHorizon(wmax,0) != null) { - result = sc.match(); - current.setWindMax(Integer.parseInt(result.group(1))); - current.setGust(Integer.valueOf(result.group(2))); - } + public void processMaxWind(int basin, boolean forecast, + TcmPositionWinds current) { + String wmax = null; + if (basin == 1) { + if (forecast) { + wmax = "MAX WIND\\s+(\\d+) KT...GUSTS\\s+(\\d+) KT"; + } else { + wmax = "SUSTAINED WINDS\\s+(\\d+) KT WITH GUSTS TO\\s+(\\d+) KT"; + } + } else if (basin == 2) { + wmax = "MAX SUSTAINED WINDS - (\\d+) KT, GUSTS\\s+(\\d+) KT"; + } + if (sc.findWithinHorizon(wmax, 0) != null) { + result = sc.match(); + current.setWindMax(Integer.parseInt(result.group(1))); + current.setGust(Integer.valueOf(result.group(2))); + } } - + /** * Process wind radii for 64 kts. * - * @param ocean basin - * @param forecast flag + * @param ocean + * basin + * @param forecast + * flag * @param TcmPositionWinds */ public void processRadii64(int basin, boolean fcst, TcmPositionWinds current) { - String KT64 = null; - if (basin == 1) { - if (fcst) { - KT64 = "64 KT...\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; - } else { - KT64 = "64 KT.......\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; - } - } else if (basin == 2) { - KT64 = "RADIUS OF 064 KT WINDS - " + - "(\\d+) NM NORTHEAST QUADRANT\\s+" + - "(\\d+) NM SOUTHEAST QUADRANT\\s+" + - "(\\d+) NM SOUTHWEST QUADRANT\\s+" + - "(\\d+) NM NORTHWEST QUADRANT"; - } - if (sc.findWithinHorizon(KT64,0) != null) { - result = sc.match(); - current.setNe64k(result.group(1)); - current.setSe64k(result.group(2)); - current.setSw64k(result.group(3)); - current.setNw64k(result.group(4)); - } - } - + String KT64 = null; + if (basin == 1) { + if (fcst) { + KT64 = "64 KT...\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; + } else { + KT64 = "64 KT.......\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; + } + } else if (basin == 2) { + KT64 = "RADIUS OF 064 KT WINDS - " + + "(\\d+) NM NORTHEAST QUADRANT\\s+" + + "(\\d+) NM SOUTHEAST QUADRANT\\s+" + + "(\\d+) NM SOUTHWEST QUADRANT\\s+" + + "(\\d+) NM NORTHWEST QUADRANT"; + } + if (sc.findWithinHorizon(KT64, 0) != null) { + result = sc.match(); + current.setNe64k(result.group(1)); + current.setSe64k(result.group(2)); + current.setSw64k(result.group(3)); + current.setNw64k(result.group(4)); + } + } + /** * Process wind radii for 50 kts. * - * @param ocean basin - * @param forecast flag + * @param ocean + * basin + * @param forecast + * flag * @param TcmPositionWinds */ public void processRadii50(int basin, boolean fcst, TcmPositionWinds current) { - String KT50 = null; - if (basin == 1) { - if (fcst) { - KT50 = "50 KT...\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; - } else { - KT50 = "50 KT.......\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; - } - } else if (basin == 2) { - KT50 = "RADIUS OF 050 KT WINDS - " + - "(\\d+) NM NORTHEAST QUADRANT\\s+" + - "(\\d+) NM SOUTHEAST QUADRANT\\s+" + - "(\\d+) NM SOUTHWEST QUADRANT\\s+" + - "(\\d+) NM NORTHWEST QUADRANT"; - } - if (sc.findWithinHorizon(KT50,0) != null) { - result = sc.match(); - current.setNe50k(result.group(1)); - current.setSe50k(result.group(2)); - current.setSw50k(result.group(3)); - current.setNw50k(result.group(4)); - } + String KT50 = null; + if (basin == 1) { + if (fcst) { + KT50 = "50 KT...\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; + } else { + KT50 = "50 KT.......\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; + } + } else if (basin == 2) { + KT50 = "RADIUS OF 050 KT WINDS - " + + "(\\d+) NM NORTHEAST QUADRANT\\s+" + + "(\\d+) NM SOUTHEAST QUADRANT\\s+" + + "(\\d+) NM SOUTHWEST QUADRANT\\s+" + + "(\\d+) NM NORTHWEST QUADRANT"; + } + if (sc.findWithinHorizon(KT50, 0) != null) { + result = sc.match(); + current.setNe50k(result.group(1)); + current.setSe50k(result.group(2)); + current.setSw50k(result.group(3)); + current.setNw50k(result.group(4)); + } } - + /** * Process wind radii for 34 kts. * - * @param ocean basin - * @param forecast flag + * @param ocean + * basin + * @param forecast + * flag * @param TcmPositionWinds */ public void processRadii34(int basin, boolean fcst, TcmPositionWinds current) { - String KT34 = null; - if (basin == 1) { - if (fcst) { - KT34 = "34 KT...\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; - } else { - KT34 = "34 KT.......\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; - } - } else if (basin == 2) { - KT34 = "RADIUS OF 034 KT WINDS - " + - "(\\d+) NM NORTHEAST QUADRANT\\s+" + - "(\\d+) NM SOUTHEAST QUADRANT\\s+" + - "(\\d+) NM SOUTHWEST QUADRANT\\s+" + - "(\\d+) NM NORTHWEST QUADRANT"; - } - if (sc.findWithinHorizon(KT34,0) != null) { - result = sc.match(); - current.setNe34k(result.group(1)); - current.setSe34k(result.group(2)); - current.setSw34k(result.group(3)); - current.setNw34k(result.group(4)); - } + String KT34 = null; + if (basin == 1) { + if (fcst) { + KT34 = "34 KT...\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; + } else { + KT34 = "34 KT.......\\s*(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; + } + } else if (basin == 2) { + KT34 = "RADIUS OF 034 KT WINDS - " + + "(\\d+) NM NORTHEAST QUADRANT\\s+" + + "(\\d+) NM SOUTHEAST QUADRANT\\s+" + + "(\\d+) NM SOUTHWEST QUADRANT\\s+" + + "(\\d+) NM NORTHWEST QUADRANT"; + } + if (sc.findWithinHorizon(KT34, 0) != null) { + result = sc.match(); + current.setNe34k(result.group(1)); + current.setSe34k(result.group(2)); + current.setSw34k(result.group(3)); + current.setNw34k(result.group(4)); + } } - + /** * Process significant wave heights. * * @param TcmRecord */ public void processWaveHeights(TcmRecord record) { - String SEAS = "12 FT SEAS..\\s+(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; - String VARY = "SEAS VARY GREATLY IN EACH QUADRANT"; - if (sc.findWithinHorizon(SEAS, 0) != null) { - result = sc.match(); - record.setNe12ft(result.group(1)); - record.setSe12ft(result.group(2)); - record.setSw12ft(result.group(3)); - record.setNw12ft(result.group(4)); - } else if (sc.findWithinHorizon(VARY, 0) != null) { - record.setNe12ft("vary"); - record.setSe12ft("vary"); - record.setSw12ft("vary"); - record.setNw12ft("vary"); - } + String SEAS = "12 FT SEAS..\\s+(\\d+)NE\\s+(\\d+)SE\\s+(\\d+)SW\\s+(\\d+)NW"; + String VARY = "SEAS VARY GREATLY IN EACH QUADRANT"; + if (sc.findWithinHorizon(SEAS, 0) != null) { + result = sc.match(); + record.setNe12ft(result.group(1)); + record.setSe12ft(result.group(2)); + record.setSw12ft(result.group(3)); + record.setNw12ft(result.group(4)); + } else if (sc.findWithinHorizon(VARY, 0) != null) { + record.setNe12ft("vary"); + record.setSe12ft("vary"); + record.setSw12ft("vary"); + record.setNw12ft("vary"); + } } - + /** * Process current storm location and valid time * - * @param ocean basin + * @param ocean + * basin * @param TcmRecord * @param TcmPositionWinds */ public void processLocationTime(int basin, TcmPositionWinds current, - TcmRecord record, Calendar cal) { - String SLOC = null; - if (basin == 1) { - SLOC = "CENTER LOCATED NEAR (\\d{0,2}.\\d{1})(N|S)\\s+(\\d{0,3}.\\d{1})" + - "(E|W) AT (\\d{1,2})/(\\d{2})(\\d{2})Z"; - if (sc.findWithinHorizon(SLOC,0) != null) { - result = sc.match(); - float lat = Float.parseFloat(result.group(1)); - if (result.group(2).equals("S")) lat *= -1.0; - current.setClat(lat); - float lon = Float.parseFloat(result.group(3)); - if (result.group(4).equals("W")) lon *= -1.0; - current.setClon(lon); + TcmRecord record, Calendar cal) { + String SLOC = null; + if (basin == 1) { + SLOC = "CENTER LOCATED NEAR (\\d{0,2}.\\d{1})(N|S)\\s+(\\d{0,3}.\\d{1})" + + "(E|W) AT (\\d{1,2})/(\\d{2})(\\d{2})Z"; + if (sc.findWithinHorizon(SLOC, 0) != null) { + result = sc.match(); + float lat = Float.parseFloat(result.group(1)); + if (result.group(2).equals("S")) + lat *= -1.0; + current.setClat(lat); + float lon = Float.parseFloat(result.group(3)); + if (result.group(4).equals("W")) + lon *= -1.0; + current.setClon(lon); - /* - * Set valid time - */ - cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(result.group(5))); - cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(result.group(6))); - cal.set(Calendar.MINUTE, Integer.parseInt(result.group(7))); - - } - } else if (basin == 2) { - SLOC = "(\\d{2})(\\d{2})(\\d{2})Z --- NEAR (\\d{0,2}.\\d{1})(N|S)\\s+" + - "(\\d{0,3}.\\d{1})(E|W)"; - if (sc.findWithinHorizon(SLOC,0) != null) { - result = sc.match(); - float lat = Float.parseFloat(result.group(4)); - if (result.group(5).equals("S")) lat *= -1.0; - current.setClat(lat); - float lon = Float.parseFloat(result.group(6)); - if (result.group(7).equals("W")) lon *= -1.0; - current.setClon(lon); + /* + * Set valid time + */ + cal.set(Calendar.DAY_OF_MONTH, + Integer.parseInt(result.group(5))); + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(result.group(6))); + cal.set(Calendar.MINUTE, Integer.parseInt(result.group(7))); - /* - * set valid time - */ - cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(result.group(1))); - cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(result.group(2))); - cal.set(Calendar.MINUTE, Integer.parseInt(result.group(3))); - } - } - processRollOver(cal, record); - - /* - * Set the current time to main and position/wind table - */ + } + } else if (basin == 2) { + SLOC = "(\\d{2})(\\d{2})(\\d{2})Z --- NEAR (\\d{0,2}.\\d{1})(N|S)\\s+" + + "(\\d{0,3}.\\d{1})(E|W)"; + if (sc.findWithinHorizon(SLOC, 0) != null) { + result = sc.match(); + float lat = Float.parseFloat(result.group(4)); + if (result.group(5).equals("S")) + lat *= -1.0; + current.setClat(lat); + float lon = Float.parseFloat(result.group(6)); + if (result.group(7).equals("W")) + lon *= -1.0; + current.setClon(lon); + + /* + * set valid time + */ + cal.set(Calendar.DAY_OF_MONTH, + Integer.parseInt(result.group(1))); + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(result.group(2))); + cal.set(Calendar.MINUTE, Integer.parseInt(result.group(3))); + } + } + processRollOver(cal, record); + + /* + * Set the current time to main and position/wind table + */ if (basin == 1) { current.setFcstHour("OBS"); record.setObsTime(cal); - } else if (basin == 2 ) { + } else if (basin == 2) { current.setFcstHour("F00"); record.setObsTime(cal); - save_time = (Calendar)cal.clone(); + save_time = (Calendar) cal.clone(); } current.setValidTime(cal); } @@ -620,179 +648,184 @@ public class TcmParser { * @param TcmRecord * @param Calendar */ - public void processLocationTime(TcmPositionWinds past,TcmRecord record, - Calendar cal) { - String PLOC = "AT (\\d{1,2})/(\\d{2})(\\d{2})Z CENTER WAS LOCATED NEAR " + - "(\\d{0,2}.\\d{1})(N|S)\\s+(\\d{0,3}.\\d{1})(E|W)"; - if (sc.findWithinHorizon(PLOC,0) != null) { - result = sc.match(); - float lat = Float.parseFloat(result.group(4)); - if (result.group(5).equals("S")) lat *= -1.0; - past.setClat(lat); - float lon = Float.parseFloat(result.group(6)); - if (result.group(7).equals("W")) lon *= -1.0; - past.setClon(lon); - } - cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(result.group(1))); - cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(result.group(2))); - cal.set(Calendar.MINUTE, Integer.parseInt(result.group(3))); - processRollOver (cal, record); + public void processLocationTime(TcmPositionWinds past, TcmRecord record, + Calendar cal) { + String PLOC = "AT (\\d{1,2})/(\\d{2})(\\d{2})Z CENTER WAS LOCATED NEAR " + + "(\\d{0,2}.\\d{1})(N|S)\\s+(\\d{0,3}.\\d{1})(E|W)"; + if (sc.findWithinHorizon(PLOC, 0) != null) { + result = sc.match(); + float lat = Float.parseFloat(result.group(4)); + if (result.group(5).equals("S")) + lat *= -1.0; + past.setClat(lat); + float lon = Float.parseFloat(result.group(6)); + if (result.group(7).equals("W")) + lon *= -1.0; + past.setClon(lon); + } + cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(result.group(1))); + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(result.group(2))); + cal.set(Calendar.MINUTE, Integer.parseInt(result.group(3))); + processRollOver(cal, record); past.setFcstHour("F00"); - save_time = (Calendar)cal.clone(); + save_time = (Calendar) cal.clone(); past.setValidTime(cal); - } - + } + /** * Process roll over month and year. */ public Calendar processRollOver(Calendar cal, TcmRecord record) { - if ( cal == null ) { - return null; - } - - if (cal.get(Calendar.DATE) < record.getIssueTime().get(Calendar.DATE)) { - if (cal.get(Calendar.MONTH) != 11) { - cal.roll(Calendar.MONTH, +1); - } - else { - cal.set(Calendar.MONTH, 0); - cal.roll(Calendar.YEAR, +1); - } - } - return cal; + if (cal == null) { + return null; + } + + if (cal.get(Calendar.DATE) < record.getIssueTime().get(Calendar.DATE)) { + if (cal.get(Calendar.MONTH) != 11) { + cal.roll(Calendar.MONTH, +1); + } else { + cal.set(Calendar.MONTH, 0); + cal.roll(Calendar.YEAR, +1); + } + } + return cal; } - + /** * Decode TCM forecast section * - * @param bull The bulletin message + * @param bull + * The bulletin message * @param record */ - public void processTcmForecasts (int basin, String bull, TcmRecord record) { - TcmPositionWinds fcst; - Calendar cal; - MatchResult result; - forecast = true; - String DM = null; - if (bull == null) { - return; - } - if (basin == 1) { - DM = "\\r\\r\\n \\r\\r\\n"; - } else if (basin == 2) { - DM = "( ---\\r\\n)|( ---\\n)"; - } - Scanner cc = new Scanner(bull).useDelimiter(DM); - if (record == null) return; + public void processTcmForecasts(int basin, String bull, TcmRecord record) { + TcmPositionWinds fcst; + Calendar cal; + MatchResult result; + forecast = true; + String DM = null; + if (bull == null) { + return; + } + if (basin == 1) { + DM = "(\\r\\r\\n \\r\\r\\n)|(\\r\\r\\n\\r\\r\\n)"; + } else if (basin == 2) { + DM = "( ---\\r\\n)|( ---\\n)"; + } + Scanner cc = new Scanner(bull).useDelimiter(DM); + if (record == null) + return; - /* - * Loop through forecast section... - */ - while (cc.hasNext()) { - String next = cc.next(); - sc = new Scanner (next); - fcst = new TcmPositionWinds(); + /* + * Loop through forecast section... + */ + while (cc.hasNext()) { + String next = cc.next(); + sc = new Scanner(next); + fcst = new TcmPositionWinds(); - /* - * Find and decode valid time and storm position. - */ - String FV = null; - if (basin == 1) { - FV = "(FORECAST|OUTLOOK) VALID (\\d{2})/(\\d{2})(\\d{2})Z " + - "(\\d{0,2}.\\d{1})(N|S)\\s+(\\d{0,3}.\\d{1})(E|W)"; - } else if (basin == 2) { - FV = "(\\w+) HRS, VALID AT:\\s+(\\d{2})(\\d{2})(\\d{2})Z --- " + - "(\\d{0,2}.\\d{1})(N|S)\\s+(\\d{0,3}.\\d{1})(E|W)"; - } + /* + * Find and decode valid time and storm position. + */ + String FV = null; + if (basin == 1) { + FV = "(FORECAST|OUTLOOK) VALID (\\d{2})/(\\d{2})(\\d{2})Z " + + "(\\d{0,2}.\\d{1})(N|S)\\s+(\\d{0,3}.\\d{1})(E|W)"; + } else if (basin == 2) { + FV = "(\\w+) HRS, VALID AT:\\s+(\\d{2})(\\d{2})(\\d{2})Z --- " + + "(\\d{0,2}.\\d{1})(N|S)\\s+(\\d{0,3}.\\d{1})(E|W)"; + } - if (sc.findWithinHorizon(FV,0) != null) { - result = sc.match(); - fcst.setFcstHour("F"+result.group(1)); + if (sc.findWithinHorizon(FV, 0) != null) { + result = sc.match(); + fcst.setFcstHour("F" + result.group(1)); - /* - * Set valid time - */ - String sdate = null; - String shour = null; - String smin = null; - cal = (Calendar) record.getIssueTime().clone(); - sdate = result.group(2); - shour = result.group(3); - smin = result.group(4); - cal.set(Calendar.DATE, Integer.parseInt(sdate)); - cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(shour)); - cal.set(Calendar.MINUTE, Integer.parseInt(smin)); - if (cal.get(Calendar.DATE) < record.getIssueTime().get(Calendar.DATE)) { - if (cal.get(Calendar.MONTH) != 11) { - cal.roll(Calendar.MONTH, +1); - } - else { - cal.set(Calendar.MONTH, 0); - cal.roll(Calendar.YEAR, +1); - } - } - fcst.setValidTime(cal); - - /* - * Compute forecast hour for TPC - */ - if (basin == 1) { - long diff = ( cal.getTime().getTime() - - save_time.getTime().getTime()) / (1000*60*60); - fcst.setFcstHour("F"+Long.toString(diff)); - } + /* + * Set valid time + */ + String sdate = null; + String shour = null; + String smin = null; + cal = (Calendar) record.getIssueTime().clone(); + sdate = result.group(2); + shour = result.group(3); + smin = result.group(4); + cal.set(Calendar.DATE, Integer.parseInt(sdate)); + cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(shour)); + cal.set(Calendar.MINUTE, Integer.parseInt(smin)); + if (cal.get(Calendar.DATE) < record.getIssueTime().get( + Calendar.DATE)) { + if (cal.get(Calendar.MONTH) != 11) { + cal.roll(Calendar.MONTH, +1); + } else { + cal.set(Calendar.MONTH, 0); + cal.roll(Calendar.YEAR, +1); + } + } + fcst.setValidTime(cal); - /* - * Set forecast location - */ - String slat = null; - String slon = null; - String south = null; - String west = null; - slat = result.group(5); - south = result.group(6); - slon = result.group(7); - west = result.group(8); + /* + * Compute forecast hour for TPC + */ + if (basin == 1) { + long diff = (cal.getTime().getTime() - save_time.getTime() + .getTime()) / (1000 * 60 * 60); + fcst.setFcstHour("F" + Long.toString(diff)); + } - float lat = Float.parseFloat(slat); - if (south.equals("S")) lat *= -1.0; - fcst.setClat(lat); - float lon = Float.parseFloat(slon); - if (west.equals("W")) lon *= -1.0; - fcst.setClon(lon); + /* + * Set forecast location + */ + String slat = null; + String slon = null; + String south = null; + String west = null; + slat = result.group(5); + south = result.group(6); + slon = result.group(7); + west = result.group(8); - /* - * Find and decode forecast wind speed and gusts - */ - processMaxWind(basin,forecast,fcst); + float lat = Float.parseFloat(slat); + if (south.equals("S")) + lat *= -1.0; + fcst.setClat(lat); + float lon = Float.parseFloat(slon); + if (west.equals("W")) + lon *= -1.0; + fcst.setClon(lon); - /* - * Find and decode forecast 64 knot wind radii. - */ - processRadii64(basin,forecast,fcst); + /* + * Find and decode forecast wind speed and gusts + */ + processMaxWind(basin, forecast, fcst); - /* - * Find and decode forecast 50 knot wind radii - */ - processRadii50(basin,forecast,fcst); + /* + * Find and decode forecast 64 knot wind radii. + */ + processRadii64(basin, forecast, fcst); - /* - * Find and decode forecast 34 knot wind radii - */ - processRadii34(basin,forecast,fcst); + /* + * Find and decode forecast 50 knot wind radii + */ + processRadii50(basin, forecast, fcst); - /* - * Find and decode storm motion. - */ - if (basin == 2) { - processStormMotion(basin,forecast,fcst); - } + /* + * Find and decode forecast 34 knot wind radii + */ + processRadii34(basin, forecast, fcst); - /* - * Add forecast storm position and winds to set. - */ - record.addPosWinds(fcst); - } - } - } + /* + * Find and decode storm motion. + */ + if (basin == 2) { + processStormMotion(basin, forecast, fcst); + } + + /* + * Add forecast storm position and winds to set. + */ + record.addPosWinds(fcst); + } + } + } } \ No newline at end of file diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java index 1ef3dce2b5..4af2953ed3 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/src/gov/noaa/nws/ncep/edex/uengine/tasks/profile/NcSoundingDrv.java @@ -29,6 +29,7 @@ package gov.noaa.nws.ncep.edex.uengine.tasks.profile; * 02/28/2012 Chin Chen modify several sounding query algorithms for better performance * 03/28/2012 Chin Chen modify Grid data sounding query algorithms for better performance * 06/25/2014 Chin Chen support dropsonde + * 07/23/2014 Chin Chen Support PW * * Python Script example to query multiple locations at one request: * The following 3 query examples, returns same results. @@ -110,6 +111,7 @@ import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.ObsSndType; import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.PfcSndType; import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile.SndQueryKeyType; import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingStnInfoCollection; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingTools; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -145,6 +147,8 @@ public class NcSoundingDrv { private int merge; + private int pwRequired = 0; // Support PW, 1=required, 0=Not required + private boolean useNcSoundingLayer2 = false; private int[] dbIdList; @@ -395,6 +399,10 @@ public class NcSoundingDrv { this.merge = merge; } + public void setPwRequired(int pwRequired) { + this.pwRequired = pwRequired; + } + public long getRefTime() { return refTime; } @@ -1189,7 +1197,21 @@ public class NcSoundingDrv { ttdd, ppaa, ppbb, ppcc, ppdd, trop_a, trop_c, wmax_a, wmax_c, pf.getStationElevation()); - + // Support PW + // System.out.println("1st merge call: lat/lon=" + // + pf.getStationLatitude()); + // for (int i = 0; i < sls.size(); i++) { + // NcSoundingLayer2 ncLay = sls.get(i); + // System.out.println(" temp=" + // + ncLay.getTemperature() + " dewp=" + // + ncLay.getDewpoint() + " press=" + // + ncLay.getPressure() + " height=" + // + ncLay.getGeoHeight() + " windSp=" + // + ncLay.getWindSpeed() + " windDir=" + // + ncLay.getWindDirection() + " omega=" + // + ncLay.getOmega()); + // } + // end Support PW if (level.toUpperCase().equalsIgnoreCase("MAN")) { pf.setSoundingLyLst2(sls); // System.out.println("sls set to the sounding profile"); @@ -1213,6 +1235,33 @@ public class NcSoundingDrv { // + level); } } + // Support PW + if (pwRequired == 1) { + List sls2 = new ArrayList(); + sls2 = ms.mergeUairSounding("-1", ttaa, ttbb, + ttcc, ttdd, ppaa, ppbb, ppcc, ppdd, + trop_a, trop_c, wmax_a, wmax_c, + pf.getStationElevation()); + pf.setPw(NcSoundingTools.precip_water2(sls2)); + + // System.out.println("2nd merge call: lat/lon=" + // + pf.getStationLatitude()); + // for (int i = 0; i < sls2.size(); i++) { + // NcSoundingLayer2 ncLay = sls2.get(i); + // System.out.println(" temp=" + // + ncLay.getTemperature() + " dewp=" + // + ncLay.getDewpoint() + " press=" + // + ncLay.getPressure() + " height=" + // + ncLay.getGeoHeight() + " windSp=" + // + ncLay.getWindSpeed() + // + " windDir=" + // + ncLay.getWindDirection() + // + " omega=" + ncLay.getOmega()); + // } + } else { + pf.setPw(-1); + } + // End Support PW } } if (pf != null && pf.getSoundingLyLst2().size() > 0) { @@ -1356,28 +1405,36 @@ public class NcSoundingDrv { // + (t02 - t01)); } cube.setSoundingProfileList(soundingProfileList); - /* - * for(int i =0; i < cube.getSoundingProfileList().size();i++){ - * System.out.println("lat/lon="+ - * cube.getSoundingProfileList().get(i).getStationLatitude - * ()+"/"+cube.getSoundingProfileList().get(i).getStationLongitude()+ - * " temp=" - * +cube.getSoundingProfileList().get(i).getSoundingLyLst2().get( - * 0).getTemperature - * ()+" dewp="+cube.getSoundingProfileList().get(i).getSoundingLyLst2 - * ().get(0).getDewpoint()+" press="+ - * cube.getSoundingProfileList().get(i - * ).getSoundingLyLst2().get(0).getPressure() + - * " height="+cube.getSoundingProfileList - * ().get(i).getSoundingLyLst2().get(0).getGeoHeight()+ - * " windSp="+cube.getSoundingProfileList - * ().get(i).getSoundingLyLst2().get - * (0).getWindSpeed()+" windDir="+cube.getSoundingProfileList - * ().get(i).getSoundingLyLst2().get(0).getWindDirection()+ - * " omega="+cube - * .getSoundingProfileList().get(i).getSoundingLyLst2().get - * (0).getOmega()); } - */ + + // for (int i = 0; i < cube.getSoundingProfileList().size(); i++) { + // System.out.println("lat/lon=" + // + cube.getSoundingProfileList().get(i).getStationLatitude() + // + "/" + // + cube.getSoundingProfileList().get(i) + // .getStationLongitude() + // + " temp=" + // + cube.getSoundingProfileList().get(i).getSoundingLyLst2() + // .get(0).getTemperature() + // + " dewp=" + // + cube.getSoundingProfileList().get(i).getSoundingLyLst2() + // .get(0).getDewpoint() + // + " press=" + // + cube.getSoundingProfileList().get(i).getSoundingLyLst2() + // .get(0).getPressure() + // + " height=" + // + cube.getSoundingProfileList().get(i).getSoundingLyLst2() + // .get(0).getGeoHeight() + // + " windSp=" + // + cube.getSoundingProfileList().get(i).getSoundingLyLst2() + // .get(0).getWindSpeed() + // + " windDir=" + // + cube.getSoundingProfileList().get(i).getSoundingLyLst2() + // .get(0).getWindDirection() + // + " omega=" + // + cube.getSoundingProfileList().get(i).getSoundingLyLst2() + // .get(0).getOmega()); + // } + returnedObject = cube; // long t02 = System.currentTimeMillis(); // System.out.println("getSoundingData2Generic query took "+(t02-t01)+" ms in total"); @@ -1984,6 +2041,10 @@ public class NcSoundingDrv { sls = ms.mergeUairSounding(level, ttaa, ttbb, ttcc, ttdd, ppaa, ppbb, ppcc, ppdd, trop_a, trop_c, wmax_a, wmax_c, pf.getStationElevation()); + // PW Support test + float pw = NcSoundingTools.precip_water(sls); + pf.setPw(pw); + // end PW Support test // System.out.println("NCUAIR Number of Layers after merge:"+sls.size() // + " level="+level + // " ms.isNumber(level)="+ms.isNumber(level)); diff --git a/ncep/gov.noaa.nws.ncep.edex.uengine/utility/edex_static/base/python/NcSoundingDataRequest.py b/ncep/gov.noaa.nws.ncep.edex.uengine/utility/edex_static/base/python/NcSoundingDataRequest.py index 3e642cc1bb..0da86c50c2 100644 --- a/ncep/gov.noaa.nws.ncep.edex.uengine/utility/edex_static/base/python/NcSoundingDataRequest.py +++ b/ncep/gov.noaa.nws.ncep.edex.uengine/utility/edex_static/base/python/NcSoundingDataRequest.py @@ -1,3 +1,11 @@ +""" + * SOFTWARE HISTORY + * + * Date Ticket# Engineer Description + * ------- ------- -------- ----------- + * 09/13/2010 301 Chin Chen Initial coding + * 07/23/2014 Chin Chen Support PW +""" from com.raytheon.uf.common.message.response import ResponseMessageGeneric from gov.noaa.nws.ncep.edex.uengine.tasks.profile import NcSoundingDrv @@ -71,6 +79,11 @@ class NcSoundingDataRequest(): def setLevel(self, level): self.NcSoundingDrv.setLevel(level) + # Support PW + def setPwRequired(self, pwRequired): + self.NcSoundingDrv.setPwRequired(pwRequired) + + def setDbIdList(self, dbIdList): #print dbIdList from jep import jarray, JINT_ID