hydro plugin updates from origin/master_18.1.1
This commit is contained in:
parent
e97d66b924
commit
eacb3727d0
72 changed files with 8923 additions and 6899 deletions
|
@ -55,7 +55,6 @@ import org.opengis.referencing.operation.TransformException;
|
|||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasin;
|
||||
import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinData;
|
||||
import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinMetaData;
|
||||
import com.raytheon.uf.common.dataplugin.ffmp.FFMPGap;
|
||||
import com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceBasin;
|
||||
|
@ -209,7 +208,6 @@ import com.vividsolutions.jts.geom.Point;
|
|||
* Sep 14, 2016 3241 bsteffen Update deprecated JTSCompiler method calls
|
||||
* Jan 23, 2017 6032 njensen Implement IExtraTextGeneratingResource
|
||||
* May 05 2017 DR 14336 lshi FFMP VGB value differences between A1 and A2
|
||||
* May 15, 2017 DR 11861 lshi FFMP use of QPF in calculating QPE in Basin Table
|
||||
* Sep 15, 2017 DR 20297 lshi FFMP AlertViz errors when changing layers and
|
||||
* opening basin trend graphs
|
||||
*
|
||||
|
@ -1931,22 +1929,14 @@ public class FFMPResource
|
|||
|
||||
float qpe = 0.0f;
|
||||
float guid = 0.0f;
|
||||
Float qpf = null;
|
||||
float diff = Float.NaN;
|
||||
String ffgType = getFFGName();
|
||||
|
||||
FFMPRecord qpfRecord = this.getQpfRecord(getPaintTime().getRefTime());
|
||||
FFMPBasinData qpfBasin = null;
|
||||
if (qpfRecord != null) {
|
||||
qpfBasin = qpfRecord.getBasinData();
|
||||
}
|
||||
|
||||
try {
|
||||
if (aggregate) {
|
||||
if (isWorstCase()) {
|
||||
List<Float> qpes = null;
|
||||
List<Float> guids = null;
|
||||
List<Float> qpfs = null;
|
||||
|
||||
if ((getQpeRecord() != null)
|
||||
&& (getGuidanceRecord() != null)) {
|
||||
|
@ -1959,12 +1949,9 @@ public class FFMPResource
|
|||
getGuidanceInterpolation(ffgType),
|
||||
getGuidSourceExpiration(ffgType));
|
||||
}
|
||||
if (qpfBasin != null) {
|
||||
qpfs = qpfBasin.getAccumValues(pfafs, getTableTime(),
|
||||
recentTime, getQpfSourceExpiration(), isRate());
|
||||
}
|
||||
|
||||
if ((qpes != null) && (guids != null)) {
|
||||
diff = FFMPUtils.getMaxDiffValue(qpes, qpfs, guids);
|
||||
diff = FFMPUtils.getMaxDiffValue(qpes, guids);
|
||||
}
|
||||
} else {
|
||||
if ((getQpeRecord() != null)
|
||||
|
@ -1980,14 +1967,7 @@ public class FFMPResource
|
|||
getGuidanceInterpolation(ffgType),
|
||||
getGuidSourceExpiration(ffgType));
|
||||
|
||||
if (qpfBasin != null) {
|
||||
qpf = qpfBasin.getAccumAverageValue(pfafs,
|
||||
getTableTime(), recentTime,
|
||||
getQpfSourceExpiration(), getResourceData()
|
||||
.getPrimarySourceXML().isRate());
|
||||
}
|
||||
|
||||
diff = FFMPUtils.getDiffValue(qpe, qpf, guid);
|
||||
diff = FFMPUtils.getDiffValue(qpe, guid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -2004,11 +1984,7 @@ public class FFMPResource
|
|||
getBasin(key, getField(), recentTime, aggregate),
|
||||
guid);
|
||||
|
||||
if (qpfBasin != null) {
|
||||
qpf = qpfBasin.get(key).getAccumValue(getTableTime(),
|
||||
recentTime, getQpfSourceExpiration(), isRate());
|
||||
}
|
||||
diff = FFMPUtils.getDiffValue(qpe, qpf, guid);
|
||||
diff = FFMPUtils.getDiffValue(qpe, guid);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -2029,22 +2005,15 @@ public class FFMPResource
|
|||
|
||||
float qpe = 0.0f;
|
||||
float guid = 0.0f;
|
||||
Float qpf = null;
|
||||
float ratio = Float.NaN;
|
||||
String ffgType = getFFGName();
|
||||
|
||||
FFMPRecord qpfRecord = this.getQpfRecord(getPaintTime().getRefTime());
|
||||
FFMPBasinData qpfBasin = null;
|
||||
if (qpfRecord != null) {
|
||||
qpfBasin = qpfRecord.getBasinData();
|
||||
}
|
||||
|
||||
try {
|
||||
if (aggregate) {
|
||||
if (isWorstCase()) {
|
||||
List<Float> qpes = null;
|
||||
List<Float> guids = null;
|
||||
List<Float> qpfs = null;
|
||||
if (getQpeRecord() != null) {
|
||||
qpes = getQpeRecord().getBasinData().getAccumValues(
|
||||
pfafs, getTableTime(), recentTime,
|
||||
|
@ -2056,13 +2025,9 @@ public class FFMPResource
|
|||
getGuidanceInterpolation(ffgType),
|
||||
getGuidSourceExpiration(ffgType));
|
||||
}
|
||||
if (qpfBasin != null) {
|
||||
qpfs = qpfBasin.getAccumValues(pfafs, getTableTime(),
|
||||
recentTime, getQpfSourceExpiration(), isRate());
|
||||
}
|
||||
|
||||
if ((qpes != null) && (guids != null)) {
|
||||
ratio = FFMPUtils.getMaxRatioValue(qpes, qpfs, guids);
|
||||
ratio = FFMPUtils.getMaxRatioValue(qpes, guids);
|
||||
}
|
||||
} else {
|
||||
if ((getQpeRecord() != null)
|
||||
|
@ -2078,14 +2043,6 @@ public class FFMPResource
|
|||
getGuidanceInterpolation(ffgType),
|
||||
getGuidSourceExpiration(ffgType));
|
||||
|
||||
if (qpfBasin != null) {
|
||||
qpf = qpfBasin.getAccumAverageValue(pfafs,
|
||||
getTableTime(), recentTime,
|
||||
getQpfSourceExpiration(), getResourceData()
|
||||
.getPrimarySourceXML().isRate());
|
||||
}
|
||||
|
||||
ratio = FFMPUtils.getRatioValue(qpe, qpf, guid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -2097,14 +2054,8 @@ public class FFMPResource
|
|||
(FFMPGuidanceBasin) getGuidanceRecord()
|
||||
.getBasinData().get(key),
|
||||
recentTime, ffgType);
|
||||
qpf = null;
|
||||
|
||||
if (qpfBasin != null) {
|
||||
qpf = qpfBasin.get(key).getAccumValue(getTableTime(),
|
||||
recentTime, getQpfSourceExpiration(), isRate());
|
||||
}
|
||||
|
||||
ratio = FFMPUtils.getRatioValue(qpe, qpf, guid);
|
||||
ratio = FFMPUtils.getRatioValue(qpe, guid);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -3404,7 +3355,6 @@ public class FFMPResource
|
|||
|
||||
Float guidancev = 0.0f;
|
||||
Float qpev = fgd.getQpe(fgdQpeTime).floatValue();
|
||||
Float qpfv = Float.NaN;
|
||||
|
||||
// Initialize to NaN. If there is no guidance then we want
|
||||
// NaN as the default value as it will be "missing".
|
||||
|
@ -3432,9 +3382,8 @@ public class FFMPResource
|
|||
|
||||
Double qpf = fgd.getQpf(fgdQpeTime);
|
||||
if (qpf != null){
|
||||
qpfv = qpf.floatValue();
|
||||
diff = FFMPUtils.getDiffValue(qpev, qpfv, guidancev);
|
||||
ratio = FFMPUtils.getRatioValue(qpev, qpfv, guidancev);
|
||||
diff = FFMPUtils.getDiffValue(qpev, guidancev);
|
||||
ratio = FFMPUtils.getRatioValue(qpev, guidancev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,6 @@ import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FfmpTableConfigData;
|
|||
* Jul 15, 2013 2184 dhladky Remove all HUC's for storage except ALL
|
||||
* Apr 30, 2014 2060 njensen Safety checks for null guidance
|
||||
* Oct 12, 2015 4948 dhladky Improved forced FFG handling.
|
||||
* Mar 07 2017 DR 11861 lshi FFMP use of QPF in Basin Table
|
||||
* Apr 12, 2017 DR 11250 lshi VGBs inclusion for localization was incorrect
|
||||
*
|
||||
* </pre>
|
||||
|
@ -179,7 +178,7 @@ public class FFMPRowGenerator implements Runnable {
|
|||
Float guidance = Float.NaN;
|
||||
Float qpe = Float.NaN;
|
||||
Float rate = Float.NaN;
|
||||
Float qpf = null;
|
||||
Float qpf = Float.NaN;
|
||||
FIELDS rowField = FIELDS.NAME;
|
||||
|
||||
if (isVGB) {
|
||||
|
@ -272,8 +271,8 @@ public class FFMPRowGenerator implements Runnable {
|
|||
|
||||
// If guidance is NaN then it cannot be > 0
|
||||
if (!qpe.isNaN() && (guidance > 0.0f)) {
|
||||
ratioValue = FFMPUtils.getRatioValue(qpe, qpf, guidance);
|
||||
diffValue = FFMPUtils.getDiffValue(qpe, qpf, guidance);
|
||||
ratioValue = FFMPUtils.getRatioValue(qpe, guidance);
|
||||
diffValue = FFMPUtils.getDiffValue(qpe, guidance);
|
||||
}
|
||||
trd.setTableCellData(i + 5, new FFMPTableCellData(
|
||||
FIELDS.RATIO, ratioValue));
|
||||
|
@ -339,8 +338,8 @@ public class FFMPRowGenerator implements Runnable {
|
|||
|
||||
// If guidance is NaN then it cannot be > 0
|
||||
if (!qpe.isNaN() && (guidance > 0.0f)) {
|
||||
ratioValue = FFMPUtils.getRatioValue(qpe, qpf, guidance);
|
||||
diffValue = FFMPUtils.getDiffValue(qpe, qpf, guidance);
|
||||
ratioValue = FFMPUtils.getRatioValue(qpe, guidance);
|
||||
diffValue = FFMPUtils.getDiffValue(qpe, guidance);
|
||||
}
|
||||
trd.setTableCellData(i + 5, new FFMPTableCellData(
|
||||
FIELDS.RATIO, ratioValue));
|
||||
|
@ -457,8 +456,8 @@ public class FFMPRowGenerator implements Runnable {
|
|||
float diffValue = Float.NaN;
|
||||
// If guidance is NaN then it cannot be > 0
|
||||
if (!qpe.isNaN() && (guidance > 0.0f)) {
|
||||
ratioValue = FFMPUtils.getRatioValue(qpe, qpf, guidance);
|
||||
diffValue = FFMPUtils.getDiffValue(qpe, qpf, guidance);
|
||||
ratioValue = FFMPUtils.getRatioValue(qpe, guidance);
|
||||
diffValue = FFMPUtils.getDiffValue(qpe, guidance);
|
||||
}
|
||||
trd.setTableCellData(i + 5, new FFMPTableCellData(
|
||||
FIELDS.RATIO, ratioValue));
|
||||
|
@ -535,7 +534,7 @@ public class FFMPRowGenerator implements Runnable {
|
|||
Float qpe = Float.NaN;
|
||||
Float guidance = Float.NaN;
|
||||
Float rate = Float.NaN;
|
||||
Float qpf = null;
|
||||
Float qpf = Float.NaN;
|
||||
Float ratioValue = Float.NaN;
|
||||
Float diffValue = Float.NaN;
|
||||
|
||||
|
@ -700,16 +699,12 @@ public class FFMPRowGenerator implements Runnable {
|
|||
ft, huc);
|
||||
}
|
||||
|
||||
List<Float> qpfs = null;
|
||||
if (qpfBasin != null ){
|
||||
qpfs = qpfBasin.getAccumValues(pfafs, monitor.getQpfWindow().getAfterTime(), monitor.getQpfWindow().getBeforeTime(), expirationTime, isRate);
|
||||
}
|
||||
|
||||
if ((!qpes.isEmpty())
|
||||
&& ((guids != null) && (!guids.isEmpty()))) {
|
||||
ratioValue = FFMPUtils
|
||||
.getMaxRatioValue(qpes, qpfs, guids);
|
||||
diffValue = FFMPUtils.getMaxDiffValue(qpes, qpfs, guids);
|
||||
.getMaxRatioValue(qpes, guids);
|
||||
diffValue = FFMPUtils.getMaxDiffValue(qpes, guids);
|
||||
}
|
||||
trd.setTableCellData(i + 5, new FFMPTableCellData(
|
||||
FIELDS.RATIO, ratioValue));
|
||||
|
@ -771,13 +766,11 @@ public class FFMPRowGenerator implements Runnable {
|
|||
Float guidance;
|
||||
Float ratioValue;
|
||||
Float diffValue;
|
||||
Float qpfValue;
|
||||
int i = 0;
|
||||
for (String guidType : guidBasins.keySet()) {
|
||||
guidance = Float.NaN;
|
||||
diffValue = Float.NaN;
|
||||
ratioValue = Float.NaN;
|
||||
qpfValue = null;
|
||||
FFFGForceUtil forceUtil = forceUtils.get(guidType);
|
||||
forceUtil.setSliderTime(sliderTime);
|
||||
|
||||
|
@ -813,19 +806,10 @@ public class FFMPRowGenerator implements Runnable {
|
|||
FIELDS.GUIDANCE, Float.NaN));
|
||||
}
|
||||
|
||||
if (qpfBasin != null) {
|
||||
FFMPBasin basin = qpfBasin.get(cBasin.getPfaf());
|
||||
if (basin != null) {
|
||||
FFMPTimeWindow window = monitor.getQpfWindow();
|
||||
qpfValue = basin.getAverageValue(window.getAfterTime(),
|
||||
window.getBeforeTime());
|
||||
}
|
||||
}
|
||||
|
||||
// If guidance is NaN then it cannot be > 0
|
||||
if (!qpe.isNaN() && (guidance > 0.0f)) {
|
||||
ratioValue = FFMPUtils.getRatioValue(qpe, qpfValue, guidance);
|
||||
diffValue = FFMPUtils.getDiffValue(qpe, qpfValue, guidance);
|
||||
ratioValue = FFMPUtils.getRatioValue(qpe, guidance);
|
||||
diffValue = FFMPUtils.getDiffValue(qpe, guidance);
|
||||
}
|
||||
trd.setTableCellData(i + 5, new FFMPTableCellData(FIELDS.RATIO,
|
||||
ratioValue));
|
||||
|
|
|
@ -55,7 +55,7 @@ class Procedure (SmartScript.SmartScript):
|
|||
tr = self.createTimeRange(0, 60, "Database", dbID)
|
||||
self.copyCmd(elements, dbID, tr)
|
||||
#Copy
|
||||
dbID = self.findDatabase("RUC80")
|
||||
dbID = self.findDatabase("RAP40")
|
||||
tr = self.createTimeRange(0, 12, "Database", dbID)
|
||||
self.copyCmd(elements, dbID, tr)
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
-->
|
||||
<fieldDisplayTypesFile>
|
||||
<field key="Wind" displayTypes="BARB,ARROW,STREAMLINE" />
|
||||
<field key="TransWind" displayTypes="BARB,ARROW,STREAMLINE" />
|
||||
<field key="LLWSWind" displayTypes="BARB,ARROW,STREAMLINE" />
|
||||
<field key="geoW" displayTypes="BARB,ARROW" />
|
||||
<field key="ageoW" displayTypes="BARB,ARROW" />
|
||||
<field key="ageoVC" displayTypes="STREAMLINE" />
|
||||
|
|
|
@ -84,6 +84,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
* 27 Apr 2016 5483 randerso Fix GUI sizing issues
|
||||
* 10/02/2017 DR20030 qzhu Fix problems of importing rating curve
|
||||
* 11/07/2017 DR19987 jdeng Can't Insert a Point in the Middle of Rating Curve Table
|
||||
* Aug. 1 2018 DR20030 jdeng Fix problems of importing rating curve, rework on all white
|
||||
* spaces.
|
||||
* </pre>
|
||||
*
|
||||
* @author lvenable
|
||||
|
@ -1192,7 +1194,7 @@ public class RatingCurveDlg extends CaveSWTDialog {
|
|||
|
||||
// Read File Line By Line
|
||||
while ((strLine = br.readLine()) != null) {
|
||||
String[] line = strLine.trim().split("\t");
|
||||
String[] line = strLine.trim().split("\\s+");
|
||||
// should be ordered stage, flow separated by a space
|
||||
if (line.length == 2) {
|
||||
rci.add(new Double(line[0]), new Double(line[1]));
|
||||
|
|
|
@ -130,6 +130,8 @@ import com.raytheon.viz.ui.editor.IMultiPaneEditor;
|
|||
* Mar 06, 2017 6161 mduff Added getFieldData()
|
||||
* Oct 06, 2017 6407 bkowal Cleanup. Updates to support GOES-R SATPRE.
|
||||
* Apr 10, 2017 17911 mgamazaychikov/wkwock Add loadRFCQPEXmrg.
|
||||
* Jun 22, 2018 7321 smanoj fixed issue with hourly grid cells not displaying according to color scale
|
||||
* and color scale on the lower left corner not displaying numeric values.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -1137,6 +1139,7 @@ public class MPEDisplayManager {
|
|||
ColorMapParameters params = new ColorMapParameters();
|
||||
params.setFormatString("0.00");
|
||||
params.setDisplayUnit(displayUnit);
|
||||
params.setDataUnit(dataUnit);
|
||||
|
||||
UnitConverter displayToData = MPEConversionUtils
|
||||
.constructConverter(displayUnit, dataUnit);
|
||||
|
@ -1199,6 +1202,10 @@ public class MPEDisplayManager {
|
|||
|
||||
params.setColorMap(new ColorMap(cvUse, red, green, blue));
|
||||
params.setDataMapping(dm);
|
||||
params.setDataMin(0);
|
||||
params.setDataMax(numColors - 1);
|
||||
params.setColorMapMin(params.getDataMin());
|
||||
params.setColorMapMax(params.getDataMax());
|
||||
|
||||
// Check for Index parameter and set labels to radar sites
|
||||
// Determine and store radar type (S/D/M) for display in legend
|
||||
|
|
|
@ -6,11 +6,16 @@ package com.raytheon.viz.mpe.ui.rfcmask;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
import com.raytheon.uf.common.mpe.util.RFCSiteLookup;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.xmrg.XmrgFile;
|
||||
import com.raytheon.viz.mpe.ui.rsc.MPEFieldResource;
|
||||
import com.raytheon.viz.mpe.ui.Activator;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -23,6 +28,7 @@ import com.raytheon.viz.mpe.ui.rsc.MPEFieldResource;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 30, 2017 17911 wkwock Initial creation
|
||||
* Jul 31, 2018 20677 wkwock Use FileLocator to open input stream.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -40,13 +46,12 @@ public class RfcMask {
|
|||
public static XmrgFile getRFCMask(String rfcSite) throws IOException {
|
||||
String rfcName = RFCSiteLookup.RFCMAP.get(rfcSite).toLowerCase();
|
||||
XmrgFile xmrgFile = new XmrgFile();
|
||||
|
||||
try (InputStream is = MPEFieldResource.class
|
||||
.getResourceAsStream("/res/RFCmask/xmrg_" + rfcName + "mask")) {
|
||||
|
||||
Bundle bundle = Activator.getDefault().getBundle();
|
||||
IPath path = new Path("/res/RFCmask/xmrg_" + rfcName + "mask");
|
||||
try (InputStream is = FileLocator.openStream(bundle, path, false)) {
|
||||
xmrgFile.load(is);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to read " + rfcName + "RFC mask file.", e);
|
||||
logger.error("Failed to read " + rfcName + " RFC mask file.", e);
|
||||
}
|
||||
|
||||
return xmrgFile;
|
||||
|
|
|
@ -60,6 +60,7 @@ import com.raytheon.viz.mpe.ui.rfcmask.RfcMask;
|
|||
* Mar 01, 2017 6160 bkowal Implemented {@link #getDisplayString()}.
|
||||
* Oct 30, 2017 17911 wkwock Display RFC QPE
|
||||
* May 04, 2018 20677 wkwock Fix display WFO QPE data issue.
|
||||
* Jul 31, 2018 20677 wkwock Add check for null pointer.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -310,7 +311,11 @@ public class MPEFieldResourceData extends AbstractMPEGriddedResourceData {
|
|||
public void maskData(MPEFieldFrame frame) {
|
||||
if (frame.origData == null) {
|
||||
frame.origData = frame.data.clone();
|
||||
frame.origEditedData = frame.editedData.clone();
|
||||
if (frame.editedData != null) {
|
||||
frame.origEditedData = frame.editedData.clone();
|
||||
} else {
|
||||
frame.origEditedData = null;
|
||||
}
|
||||
|
||||
if (maskXmrg == null) {
|
||||
AppsDefaults appsDefaults = AppsDefaults.getInstance();
|
||||
|
@ -336,7 +341,9 @@ public class MPEFieldResourceData extends AbstractMPEGriddedResourceData {
|
|||
for (int i = 0; i < maskData.length; i++) {
|
||||
if (maskData[i] == 0) {
|
||||
frame.data[i] = CommonHydroConstants.MISSING_VALUE;
|
||||
frame.editedData[i] = CommonHydroConstants.MISSING_VALUE;
|
||||
if (frame.editedData != null) {
|
||||
frame.editedData[i] = CommonHydroConstants.MISSING_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</configIni>
|
||||
|
||||
<launcherArgs>
|
||||
<programArgs>-data @user.home/caveData -user @user.home/caveData
|
||||
<programArgs>-data @user.home/caveData -user @user.home/caveData -alertviz -vm "C:/Program Files/Raytheon/AWIPS II/Java/jre/bin/javaw.exe"
|
||||
</programArgs>
|
||||
<programArgsLin>-consoleLog
|
||||
</programArgsLin>
|
||||
|
@ -63,11 +63,13 @@
|
|||
</win>
|
||||
</launcher>
|
||||
|
||||
|
||||
<vm>
|
||||
<linux include="true">jdk1.7.0</linux>
|
||||
<windows include="true">jdk1.7.0</windows>
|
||||
</vm>
|
||||
|
||||
|
||||
<plugins>
|
||||
</plugins>
|
||||
|
||||
|
@ -104,15 +106,19 @@
|
|||
<feature id="com.raytheon.uf.viz.ncep.perspective.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.thinclient.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.npp.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.d2d.skewt.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.npp.sounding.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.d2d.skewt.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.acarssounding.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.viz.avnfps.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.viz.hydro.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.dat.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.d2d.gfe.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.d2d.damagepath.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.gisdatastore.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.d2d.ui.awips.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.alertview.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.d2d.damagepath.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.ffmp.feature" version="1.0.0.qualifier"/>
|
||||
<feature id="com.raytheon.uf.viz.scan.feature" version="1.0.0.qualifier"/>
|
||||
</features>
|
||||
|
||||
<configurations>
|
||||
|
@ -122,4 +128,11 @@
|
|||
<plugin id="org.eclipse.equinox.ds" autoStart="true" startLevel="2" />
|
||||
</configurations>
|
||||
|
||||
<preferencesInfo>
|
||||
<targetfile overwrite="false"/>
|
||||
</preferencesInfo>
|
||||
|
||||
<cssInfo>
|
||||
</cssInfo>
|
||||
|
||||
</product>
|
||||
|
|
|
@ -24,18 +24,13 @@ import java.nio.Buffer;
|
|||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.measure.unit.Unit;
|
||||
import javax.measure.unit.UnitFormat;
|
||||
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData;
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.units.goes.PolarPrecipWaterPixel;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.units.water.BlendedTPWPixel;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.units.SatelliteUnitsUtil;
|
||||
import com.raytheon.uf.common.datastorage.DataStoreFactory;
|
||||
import com.raytheon.uf.common.datastorage.Request;
|
||||
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
|
||||
|
@ -48,7 +43,6 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
|
||||
import com.raytheon.uf.viz.datacube.DataCubeContainer;
|
||||
import com.raytheon.viz.satellite.SatelliteConstants;
|
||||
|
||||
/**
|
||||
* {@link IColorMapDataRetrievalCallback} for satellite imagery data. Supports
|
||||
|
@ -66,11 +60,11 @@ import com.raytheon.viz.satellite.SatelliteConstants;
|
|||
* Apr 09, 2014 2947 bsteffen Improve flexibility of sat derived
|
||||
* parameters.
|
||||
* Apr 15, 2014 4388 bsteffen Add method to get signed vs. unsigned from data record.
|
||||
* Jul 31, 2018 6389 mapeters Units methods extracted to SatelliteUnitsUtil
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SatDataRetriever implements IColorMapDataRetrievalCallback {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
|
@ -100,10 +94,10 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
|
|||
Buffer data = null;
|
||||
Unit<?> dataUnit = Unit.ONE;
|
||||
boolean signed = false;
|
||||
Request req = Request.buildSlab(new int[] { this.datasetBounds.x,
|
||||
this.datasetBounds.y }, new int[] {
|
||||
this.datasetBounds.x + this.datasetBounds.width,
|
||||
this.datasetBounds.y + this.datasetBounds.height });
|
||||
Request req = Request.buildSlab(
|
||||
new int[] { this.datasetBounds.x, this.datasetBounds.y },
|
||||
new int[] { this.datasetBounds.x + this.datasetBounds.width,
|
||||
this.datasetBounds.y + this.datasetBounds.height });
|
||||
IDataRecord[] dataRecord = null;
|
||||
try {
|
||||
dataRecord = DataCubeContainer.getDataRecord(record, req,
|
||||
|
@ -141,84 +135,34 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
|
|||
dataType = ColorMapData.getDataType(data);
|
||||
}
|
||||
|
||||
return new ColorMapData(data, new int[] { datasetBounds.width,
|
||||
datasetBounds.height }, dataType, dataUnit);
|
||||
return new ColorMapData(data,
|
||||
new int[] { datasetBounds.width, datasetBounds.height },
|
||||
dataType, dataUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param record2
|
||||
* @return
|
||||
* @deprecated use {@link SatelliteUnitsUtil#getRecordUnit(SatelliteRecord)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Unit<?> getRecordUnit(SatelliteRecord record) {
|
||||
Unit<?> recordUnit = null;
|
||||
String physicalElement = record.getPhysicalElement();
|
||||
|
||||
if (record.getUnits() != null && record.getUnits().isEmpty() == false) {
|
||||
try {
|
||||
recordUnit = UnitFormat.getUCUMInstance().parseProductUnit(
|
||||
record.getUnits(), new ParsePosition(0));
|
||||
} catch (ParseException e) {
|
||||
statusHandler
|
||||
.handle(Priority.PROBLEM,
|
||||
"Unable to parse satellite units: "
|
||||
+ record.getUnits(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (physicalElement.equals(SatelliteConstants.PRECIP)) {
|
||||
String creatingEntity = record.getCreatingEntity();
|
||||
if (creatingEntity.equals(SatelliteConstants.DMSP)
|
||||
|| creatingEntity.equals(SatelliteConstants.POES)) {
|
||||
recordUnit = new PolarPrecipWaterPixel();
|
||||
} else if (creatingEntity.equals(SatelliteConstants.MISC)) {
|
||||
recordUnit = new BlendedTPWPixel();
|
||||
}
|
||||
}
|
||||
|
||||
return recordUnit;
|
||||
return SatelliteUnitsUtil.getRecordUnit(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the data units for the data record given the PDO's base unit
|
||||
*
|
||||
* @param recordUnit
|
||||
* @param dataRecord
|
||||
* @return
|
||||
* @deprecated use {@link SatelliteUnitsUtil#getDataUnit(Unit, IDataRecord)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Unit<?> getDataUnit(Unit<?> recordUnit,
|
||||
IDataRecord dataRecord) {
|
||||
Unit<?> units = recordUnit != null ? recordUnit : Unit.ONE;
|
||||
Map<String, Object> attrs = dataRecord.getDataAttributes();
|
||||
if (attrs != null) {
|
||||
Number offset = (Number) attrs.get(SatelliteRecord.SAT_ADD_OFFSET);
|
||||
Number scale = (Number) attrs.get(SatelliteRecord.SAT_SCALE_FACTOR);
|
||||
|
||||
if (offset != null) {
|
||||
double offsetVal = offset.doubleValue();
|
||||
if (offsetVal != 0.0) {
|
||||
units = units.plus(offsetVal);
|
||||
}
|
||||
}
|
||||
if (scale != null) {
|
||||
double scaleVal = scale.doubleValue();
|
||||
if (scaleVal != 0.0) {
|
||||
units = units.times(scaleVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return units;
|
||||
return SatelliteUnitsUtil.getDataUnit(recordUnit, dataRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link SatelliteUnitsUtil#isSigned(IDataRecord)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isSigned(IDataRecord record) {
|
||||
Map<String, Object> attrs = record.getDataAttributes();
|
||||
if (attrs != null) {
|
||||
Boolean signed = (Boolean) attrs
|
||||
.get(SatelliteRecord.SAT_SIGNED_FLAG);
|
||||
if (signed != null && signed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return SatelliteUnitsUtil.isSigned(record);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -244,28 +188,37 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
|
|||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
if (this == obj) {
|
||||
return true;
|
||||
if (obj == null)
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
SatDataRetriever other = (SatDataRetriever) obj;
|
||||
if (dataset == null) {
|
||||
if (other.dataset != null)
|
||||
if (other.dataset != null) {
|
||||
return false;
|
||||
} else if (!dataset.equals(other.dataset))
|
||||
}
|
||||
} else if (!dataset.equals(other.dataset)) {
|
||||
return false;
|
||||
}
|
||||
if (datasetBounds == null) {
|
||||
if (other.datasetBounds != null)
|
||||
if (other.datasetBounds != null) {
|
||||
return false;
|
||||
} else if (!datasetBounds.equals(other.datasetBounds))
|
||||
}
|
||||
} else if (!datasetBounds.equals(other.datasetBounds)) {
|
||||
return false;
|
||||
}
|
||||
if (record == null) {
|
||||
if (other.record != null)
|
||||
if (other.record != null) {
|
||||
return false;
|
||||
} else if (!record.equals(other.record))
|
||||
}
|
||||
} else if (!record.equals(other.record)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,26 +24,72 @@
|
|||
of the file.
|
||||
-->
|
||||
<menuTemplate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<contribute xsi:type="menuItem" menuText="Max Temp" key="MxT12hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Min Temp" key="MnT12hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Min Rel Humidity" key="MINRH12hr" />
|
||||
<contribute xsi:type="toolbarSubMenu" menuText="Aviation">
|
||||
<contribute xsi:type="menuItem" menuText="Cloud Base" key="CC" />
|
||||
<contribute xsi:type="menuItem" menuText="Echo Tops" key="RETOP" />
|
||||
<contribute xsi:type="menuItem" menuText="LLWS Height" key="LLWSHgt" />
|
||||
<contribute xsi:type="menuItem" menuText="LLWS Wind" key="LLWSWind" />
|
||||
<contribute xsi:type="menuItem" menuText="Simulated Maximum Reflectivity" key="MAXREFmax1hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Total Cloud Cover" key="TCC" />
|
||||
<contribute xsi:type="menuItem" menuText="Vertically Integrated Liquid" key="VILIQ" />
|
||||
<contribute xsi:type="menuItem" menuText="Visibility" key="Vis" />
|
||||
</contribute>
|
||||
|
||||
<contribute xsi:type="toolbarSubMenu" menuText="FireWx">
|
||||
<contribute xsi:type="menuItem" menuText="Fosberg Fire Weather index" key="FOSINDX6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Haines Index" key="HINDEX6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Mixing Height" key="MIXHT" />
|
||||
<contribute xsi:type="menuItem" menuText="Transport Wind" key="TransWind" />
|
||||
<contribute xsi:type="menuItem" menuText="Ventilation Rate" key="VRATE" />
|
||||
</contribute>
|
||||
|
||||
<contribute xsi:type="toolbarSubMenu" menuText="Winter Wx">
|
||||
<contribute xsi:type="menuItem" menuText="1-h Ice Accumulation" key="FICEAC1hr" />
|
||||
<contribute xsi:type="menuItem" menuText="6-h Ice Accumulation" key="FICEAC6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Max Wet Bulb Temp" key="MaxTW" />
|
||||
<contribute xsi:type="menuItem" menuText="Negative Energy Low-level" key="NBE" />
|
||||
<contribute xsi:type="menuItem" menuText="Positive Energy Aloft" key="PBE" />
|
||||
<contribute xsi:type="menuItem" menuText="Predominant Weather" key="PWTHER" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Cloud Ice" key="PrbCldIce" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Freezing Rain" key="PTypFreezingRain" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Ice Pellets" key="PTypIcePellets" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Rain" key="PTypRain" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Refreeze Ice Plts" key="PTypeRefIP" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Snow" key="PTypSnow" />
|
||||
<contribute xsi:type="menuItem" menuText="1-h Snow Accumulation" key="TOTSN1hr" />
|
||||
<contribute xsi:type="menuItem" menuText="6-h Snow Accumulation" key="TOTSN6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Snow-Liquid Ratio" key="SNOWRATIO" />
|
||||
<contribute xsi:type="menuItem" menuText="Snow Level" key="SNOWLVL" />
|
||||
</contribute>
|
||||
|
||||
<contribute xsi:type="toolbarSubMenu" menuText="Tstorm">
|
||||
<contribute xsi:type="menuItem" menuText="12-h Prob. of a Thunderstorm" key="ThP12hr" />
|
||||
<contribute xsi:type="menuItem" menuText="3-h SREF-based Prob. of a Dry Thunderstorm" key="DRYTPPROB3hr" />
|
||||
<contribute xsi:type="menuItem" menuText="1-h SREF-based Prob. of a Thunderstorm" key="ThP1hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Tstorm Prob 3hr" key="ThP3hr" />
|
||||
</contribute>
|
||||
|
||||
<contribute xsi:type="toolbarSubMenu" menuText="Oceanic">
|
||||
<contribute xsi:type="menuItem" menuText="50th Percentile Air temperature" key="T50pct" />
|
||||
<contribute xsi:type="menuItem" menuText="10th Percentile Mean Sea Level Pressure" key="PMSL10pct" />
|
||||
<contribute xsi:type="menuItem" menuText="50th Percentile Mean Sea Level Pressure" key="PMSL50pct" />
|
||||
<contribute xsi:type="menuItem" menuText="90th Percentile Mean Sea Level Pressure" key="PMSL90pct" />
|
||||
<contribute xsi:type="menuItem" menuText="10-m Wind Gust" key="WGS50pct" />
|
||||
<contribute xsi:type="menuItem" menuText="30-m/80-m Wind Speed" key="WS50pct" />
|
||||
</contribute>
|
||||
|
||||
<contribute xsi:type="menuItem" menuText="Max Rel Humidity" key="MAXRH12hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Max Wet Bulb Temp" key="MaxTW" />
|
||||
<contribute xsi:type="menuItem" menuText="Max Temp" key="MxT12hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Min Rel Humidity" key="MINRH12hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Min Temp" key="MnT12hr" />
|
||||
<contribute xsi:type="menuItem" menuText="10th percentile 6-h Quant" key="TP10pct6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="50th percentile 6-h Quant" key="TP50pct6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="90th percentile 6-h Quant" key="TP90pct6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="POP 12hr" key="POP12hr" />
|
||||
<contribute xsi:type="menuItem" menuText="1hr Precip Pot Idx" key="PPI1hr" />
|
||||
<contribute xsi:type="menuItem" menuText="6hr Precip Pot Idx" key="PPI6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="1hr Precip Accum" key="TP1hr" />
|
||||
<contribute xsi:type="menuItem" menuText="6hr Precip Accum" key="TP6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Cloud Ice" key="PrbCldIce" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Rain" key="PTypRain" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Freezing Rain" key="PTypFreezingRain" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Snow" key="PTypSnow" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Ice Pellets" key="PTypIcePellets" />
|
||||
<contribute xsi:type="menuItem" menuText="Prob Refreeze Ice Plts" key="PTypeRefIP" />
|
||||
<contribute xsi:type="menuItem" menuText="Total Cloud Cover" key="TCC" />
|
||||
<contribute xsi:type="menuItem" menuText="Snow-Liquid Ratio" key="SNOWRATIO" />
|
||||
<contribute xsi:type="menuItem" menuText="Snow Level" key="SNOWLVL" />
|
||||
<contribute xsi:type="menuItem" menuText="Visibility" key="Vis" />
|
||||
<contribute xsi:type="menuItem" menuText="Tstorm Prob 3hr" key="ThP3hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Tstorm Prob 6hr" key="ThP6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="1hr Precip Potential Index" key="PPI1hr" />
|
||||
<contribute xsi:type="menuItem" menuText="6hr Precip Potential Index" key="PPI6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="6-h Prob. of Precipitation" key="POP6hr" />
|
||||
<contribute xsi:type="menuItem" menuText="Significant Wave Height" key="HTSGW" />
|
||||
</menuTemplate>
|
|
@ -81,6 +81,7 @@
|
|||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="120agl" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="150agl" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="400agl" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="0.61-40kmAgl" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="EchoTop" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="El" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="SIG0.8-0.5"
|
||||
|
@ -160,4 +161,9 @@
|
|||
indentText="false" />
|
||||
</contribute>
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="NTAT" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="2FHAG" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="10FHAG" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="0-0.61kmAgl" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="30mAgl" indentText="false" />
|
||||
<contribute xsi:type="menuItem" textLookup="LevelMapping" key="80mAgl" indentText="false" />
|
||||
</menuTemplate>
|
|
@ -29,14 +29,12 @@
|
|||
id="com.raytheon.viz.volumebrowser.volumeBrowser"
|
||||
name="Volume Browser">
|
||||
</command>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.commands">
|
||||
<command
|
||||
id="com.raytheon.viz.volumebrowser.volumeBrowserRef"
|
||||
name="Volume Browser">
|
||||
<commandParameter
|
||||
id="viewType"
|
||||
name="viewType"
|
||||
optional="false">
|
||||
</commandParameter>
|
||||
</command>
|
||||
</extension>
|
||||
<extension
|
||||
|
@ -57,14 +55,14 @@
|
|||
<path
|
||||
application="D2D"
|
||||
localizationType="CAVE_STATIC,COMMON_STATIC"
|
||||
name="Volume Browser Sources"
|
||||
value="volumebrowser"
|
||||
name="Volume Browser"
|
||||
value="level/mappings"
|
||||
recursive="true">
|
||||
</path>
|
||||
<path
|
||||
application="D2D"
|
||||
localizationType="CAVE_STATIC"
|
||||
name="Volume Browser Height Scales"
|
||||
name="Height Scales"
|
||||
value="scales"
|
||||
recursive="true">
|
||||
</path>
|
||||
|
@ -75,7 +73,7 @@
|
|||
locationURI="menu:volume?after=top">
|
||||
<command
|
||||
commandId="com.raytheon.viz.volumebrowser.volumeBrowserRef"
|
||||
label="Volume Browser">
|
||||
label="Browser...">
|
||||
</command>
|
||||
<separator name="afterVB" visible="false"/>
|
||||
<separator name="VolumeBundles" visible="true"/>
|
||||
|
|
|
@ -126,6 +126,14 @@ NWS_ROLE_DATA = {
|
|||
]
|
||||
}
|
||||
|
||||
def formatElement(element):
|
||||
s = "<" + element.tag
|
||||
if element.attrib:
|
||||
for id, value in element.items():
|
||||
s += ' %s="%s"' % (id, value)
|
||||
s += ">"
|
||||
return s
|
||||
|
||||
def validateSchema(element, schema):
|
||||
# validates the xml is syntactically correct based on the provided schema
|
||||
# there is no validation of the content, just the format
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
# overrides of these files.
|
||||
##
|
||||
|
||||
import copy
|
||||
import logging
|
||||
import glob
|
||||
import imp
|
||||
import os
|
||||
import os.path
|
||||
import pprint
|
||||
import re
|
||||
import shutil
|
||||
|
||||
|
||||
|
@ -141,48 +142,86 @@ from DefaultCityLocation import CityLocation
|
|||
|
||||
|
||||
def create_incremental_area_dictionary():
|
||||
for file in glob.iglob(AREA_DICT_GLOB_PATH):
|
||||
log.info("Generating incremental override file [%s]...", file)
|
||||
for site_file in glob.iglob(AREA_DICT_GLOB_PATH):
|
||||
log.info("Generating incremental override file [%s]...", site_file)
|
||||
|
||||
base_file = file.replace("site", "configured", 1)
|
||||
base_file = site_file.replace("site", "configured", 1)
|
||||
if not os.path.isfile(base_file):
|
||||
log.error("Could not find CONFIGURED level file [%s].", base_file)
|
||||
log.error("Skipping to next file.")
|
||||
continue
|
||||
|
||||
log.debug("Using configured file [%s]...", base_file)
|
||||
log.debug("Using site file [%s]...", file)
|
||||
with open(site_file, 'r') as f:
|
||||
contents = f.read()
|
||||
if "from DefaultAreaDictionary import AreaDictionary" in contents:
|
||||
log.info("Site AreaDictionary file [%s] has already been upgraded.", site_file)
|
||||
continue
|
||||
|
||||
log.info("Using configured file [%s]...", base_file)
|
||||
log.info("Using site file [%s]...", site_file)
|
||||
|
||||
configured_module = imp.load_source('base', base_file)
|
||||
site_module = imp.load_source('override', file)
|
||||
site_module = imp.load_source('override', site_file)
|
||||
configured_dict = configured_module.AreaDictionary
|
||||
site_dict = site_module.AreaDictionary
|
||||
|
||||
diffs = diff_dicts(configured_dict, site_dict)
|
||||
log.debug("AreaDictionary Differences: %r", diffs)
|
||||
write_override_file(file, 'AreaDictionary', diffs, AREA_DICT_HEADER)
|
||||
write_override_file(site_file, 'AreaDictionary', diffs, AREA_DICT_HEADER)
|
||||
|
||||
delete_files(base_file + '*')
|
||||
|
||||
def create_incremental_city_location():
|
||||
for file in glob.iglob(CITY_LOC_GLOB_PATH):
|
||||
log.info("Generating incremental override file [%s]...", file)
|
||||
for site_file in glob.iglob(CITY_LOC_GLOB_PATH):
|
||||
log.info("Generating incremental override file [%s]...", site_file)
|
||||
|
||||
base_file = file.replace("site", "configured", 1)
|
||||
base_file = site_file.replace("site", "configured", 1)
|
||||
if not os.path.isfile(base_file):
|
||||
log.error("Could not find CONFIGURED level file [%s].", base_file)
|
||||
log.error("Skipping to next file..")
|
||||
log.error("Skipping to next file.")
|
||||
continue
|
||||
|
||||
log.debug("Using configured file [%s]...", base_file)
|
||||
log.debug("Using site file [%s]...", file)
|
||||
with open(site_file, 'r') as f:
|
||||
contents = f.read()
|
||||
if "from DefaultCityLocation import CityLocation" in contents:
|
||||
log.info("Site CityLocation file [%s] has already been upgraded.", site_file)
|
||||
continue
|
||||
|
||||
log.info("Using configured file [%s]...", base_file)
|
||||
log.info("Using site file [%s]...", site_file)
|
||||
|
||||
configured_module = imp.load_source('base', base_file)
|
||||
site_module = imp.load_source('override', file)
|
||||
site_module = imp.load_source('override', site_file)
|
||||
configured_dict = configured_module.CityLocation
|
||||
site_dict = site_module.CityLocation
|
||||
|
||||
diffs = diff_dicts(configured_dict, site_dict)
|
||||
log.debug("CityLocation Differences: %r", diffs)
|
||||
write_override_file(file, 'CityLocation', diffs, CITY_LOCATION_HEADER)
|
||||
write_override_file(site_file, 'CityLocation', diffs, CITY_LOCATION_HEADER)
|
||||
|
||||
def diff_dicts(base, override, level=0):
|
||||
delete_files(base_file + '*')
|
||||
|
||||
def diff_dicts(base, override):
|
||||
differences = []
|
||||
|
||||
keys = set().union(base.keys(), override.keys())
|
||||
# log.debug("Combined keys: %s", keys)
|
||||
|
||||
for key in sorted(keys):
|
||||
if key not in base:
|
||||
log.debug("Key [%s] in override, but not base.", key)
|
||||
differences.append((key, copy.copy(override[key]), True))
|
||||
elif key not in override:
|
||||
log.debug("Key [%s] in base, but not override.", key)
|
||||
else:
|
||||
sub_diffs = sub_diff_dicts(base[key], override[key])
|
||||
if sub_diffs:
|
||||
log.debug("Differences for key [%s]: %r", key, sub_diffs)
|
||||
differences.append((key, sub_diffs, False))
|
||||
|
||||
return differences
|
||||
|
||||
def sub_diff_dicts(base, override, level=0):
|
||||
differences = {}
|
||||
|
||||
keys = set().union(base.keys(), override.keys())
|
||||
|
@ -191,45 +230,50 @@ def diff_dicts(base, override, level=0):
|
|||
for key in sorted(keys):
|
||||
if key not in base:
|
||||
log.debug("Key [%s] in override, but not base.", key)
|
||||
differences[key] = override[key].copy()
|
||||
differences[key] = copy.copy(override[key])
|
||||
elif key not in override:
|
||||
log.debug("Key [%s] in base, but not override.", key)
|
||||
else:
|
||||
if level != 1:
|
||||
sub_diffs = diff_dicts(base[key], override[key], level+1)
|
||||
if sub_diffs:
|
||||
log.debug("Differences for key [%s]: %r", key, sub_diffs)
|
||||
differences[key] = sub_diffs
|
||||
else:
|
||||
if base[key] != override[key]:
|
||||
if base[key] != override[key]:
|
||||
differences[key] = override[key]
|
||||
|
||||
return differences
|
||||
|
||||
def write_override_file(file, object_name, object_value, header):
|
||||
backup_file = file + ".bak.dr_6346"
|
||||
def write_override_file(file_name, object_name, object_value, header):
|
||||
backup_file = file_name + ".bak.dr_6346"
|
||||
log.info("Writing backup file [%s]", backup_file)
|
||||
try:
|
||||
shutil.copy(file, backup_file)
|
||||
shutil.copy(file_name, backup_file)
|
||||
except:
|
||||
log.exception("Unable to write backup file [%s]", backup_file)
|
||||
log.error("Skipping file [%s]", file)
|
||||
log.error("Skipping file [%s]", file_name)
|
||||
return
|
||||
|
||||
log.info("Writing override file [%s]", file)
|
||||
log.info("Writing override file [%s]", file_name)
|
||||
try:
|
||||
with open(file, 'w') as out_file:
|
||||
with open(file_name, 'w') as out_file:
|
||||
printer = pprint.PrettyPrinter()
|
||||
|
||||
out_file.write(header)
|
||||
for key in sorted(object_value.keys()):
|
||||
for sub_key in sorted(object_value[key].keys()):
|
||||
out_file.write("{}[{}][{}] = {}".format(object_name, key, sub_key, printer.pformat(object_value[key][sub_key])))
|
||||
for (key, value, added) in sorted(object_value, key=lambda i: i[0]):
|
||||
if added:
|
||||
out_file.write("{}[{!r}] = {}".format(object_name, key, printer.pformat(value)))
|
||||
out_file.write('\n')
|
||||
else:
|
||||
for sub_key in sorted(value.keys()):
|
||||
out_file.write("{}[{!r}][{!r}] = {}".format(object_name, key, sub_key, printer.pformat(value[sub_key])))
|
||||
out_file.write('\n')
|
||||
out_file.write('\n')
|
||||
except:
|
||||
log.exception("Unable to write incremental override file [%s]", file)
|
||||
log.critical("Restore backup file [%s] to [%s] before restarting EDEX.", backup_file, file)
|
||||
log.exception("Unable to write incremental override file [%s]", file_name)
|
||||
log.critical("Restore backup file [%s] to [%s] before restarting EDEX.", backup_file, file_name)
|
||||
|
||||
def delete_files(file_pattern):
|
||||
for f in glob.iglob(file_pattern):
|
||||
try:
|
||||
os.remove(f)
|
||||
except:
|
||||
log.exception("Unable to delete file [%s].", f)
|
||||
|
||||
def main():
|
||||
log.info("Starting delta script for DR #6346: creating incremental overrides for AreaDictionary.py and CityLocation.py...")
|
||||
|
|
11
deltaScripts/18.1.1/DR7424/addGridCoverageIndex.sh
Normal file
11
deltaScripts/18.1.1/DR7424/addGridCoverageIndex.sh
Normal file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
# #7424 - This script adds an index to the grid_info table's location column to
|
||||
# allow for faster lookup and deletion of large numbers of grid_coverage.
|
||||
#
|
||||
# NOTE: This script will error if the index already exists, but this will not
|
||||
# negatively impact the system.
|
||||
|
||||
# run the update
|
||||
echo "DR #7427 - Adding index to grid_info.location..."
|
||||
/awips2/psql/bin/psql -U awipsadmin -d metadata -c "CREATE INDEX grid_info_location_id_index ON grid_info USING btree (location_id);"
|
|
@ -82,7 +82,7 @@ td:first-child { font-weight: bold }
|
|||
| lsr | Local Storm Reports |
|
||||
| mpe | Multi-sensor Precipitation Estimation |
|
||||
| preciprate | Precipitation Rate from SCAN. Raw data input: radar data [with WSR-88D product mnemonic and number] needed for preciprate are Digital Hybrid Reflectivity [DHR, 32]. |
|
||||
| qpf | Quantitative Precipitation Forecast from SCAN. (raw data inputs: radar and some RUC130 fields. Radar data [with WSR-88D product mnemonics and numbers] needed for SCAN’s QPF are 0.5 degree Base Reflectivity [Z, 19], 4 km Vertically Integrated Liquid [VIL, 57], and Storm Track [STI, 58]. The RUC130 field needed is 700 mb Wind, as defined in the SCANRunSiteConfig.xml file.) |
|
||||
| qpf | Quantitative Precipitation Forecast from SCAN. (raw data inputs: radar and some RAP13 fields. Radar data [with WSR-88D product mnemonics and numbers] needed for SCAN’s QPF are 0.5 degree Base Reflectivity [Z, 19], 4 km Vertically Integrated Liquid [VIL, 57], and Storm Track [STI, 58]. The RAP13 field needed is 700 mb Wind, as defined in the SCANRunSiteConfig.xml file.) |
|
||||
| satpre | Satellite-estimated Pecipiration (hydroApps) |
|
||||
| scan | SCAN (System for Convection Analysis and Nowcasting). (Inputs for the SCAN Table include radar, cloud-to-ground lightning from the NLDN, fields from RAP13, and CWAT. Specific radar products [with WSR-88D product mnemonics and numbers] are: 1 km Composite Reflectivity [CZ, 37]; 0.5 degree Base Reflectivity [Z, 19]; 4 km Vertically Integrated Liquid [VIL, 57]; Storm Track [STI, 58]; Mesocyclone Detections [MD, 141]; and Tornadic Vortex Signature [TVS, 61]. |
|
||||
| shef | Standard Hydrometeorological Exchange Format data. |
|
||||
|
|
|
@ -18,6 +18,15 @@ Every server should have one line for every server in the replication setup,
|
|||
including itself--thus all servers should have the same lines. This enables
|
||||
quickly changing which server is the master without extra configuration.
|
||||
|
||||
Also you need to add a SSL certificate and key for the "replication" DB role.
|
||||
You have to create these files yourself, except for root.crt which is the
|
||||
root certificate for the database--you can copy that one straight from
|
||||
/awips2/database/ssl. Put them here:
|
||||
|
||||
/awips2/database/ssl/replication/${hostname -s}/replication.crt
|
||||
/awips2/database/ssl/replication/${hostname -s}/replication.key
|
||||
/awips2/database/ssl/replication/${hostname -s}/root.crt
|
||||
|
||||
|
||||
SETTING UP STANDBYS
|
||||
-------------------
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
##
|
||||
# This software was developed and / or modified by Raytheon Company,
|
||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
#
|
||||
|
@ -18,6 +18,23 @@
|
|||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
# further licensing information.
|
||||
#
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
#
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# Sep 22, 2016 5885 tgurney Initial creation
|
||||
# Jan 4, 2017 6056 tgurney Fix tmp dir cleanup
|
||||
# Mar 16, 2017 6184 tgurney Update to fetch and use SSL certificates
|
||||
# Mar 29, 2017 6184 tgurney Fix SSL certificate sync from master
|
||||
# Apr 4, 2017 6184 tgurney Set correct permissions on cert directory
|
||||
# Apr 4, 2017 6122 tgurney Move database to /awips2/database
|
||||
# + cleanup and fixes for postgres 9.5.x
|
||||
# Aug 6, 2018 7431 tgurney Bug fixes. Allow starting without a
|
||||
# pg_hba.conf on standby server
|
||||
#
|
||||
##
|
||||
|
||||
|
||||
# Configuration ###############################################################
|
||||
|
||||
|
@ -37,7 +54,7 @@ ssl_dir=/awips2/database/ssl
|
|||
tablespace_dir=/awips2/database/tablespaces
|
||||
|
||||
# pg_hba.conf backup location
|
||||
hba_backup="$(mktemp pg_hba.backup.XXXXXX)"
|
||||
hba_backup="$(mktemp /tmp/pg_hba.backup.XXXXXX)"
|
||||
rm -f "${hba_backup}"
|
||||
|
||||
# For logging the output of this script
|
||||
|
@ -54,7 +71,7 @@ pg_basebackup=${pg_dir}/bin/pg_basebackup
|
|||
pg_ctl=${pg_dir}/bin/pg_ctl
|
||||
psql=/awips2/psql/bin/psql
|
||||
|
||||
${as_awips}='sudo -u awips -i '
|
||||
as_awips='sudo -u awips -i '
|
||||
|
||||
log() {
|
||||
echo $* | ${as_awips} tee -a "${log_file}"
|
||||
|
@ -73,22 +90,26 @@ stop_server() {
|
|||
do_pg_ctl -m fast stop && sleep 1
|
||||
do_pg_ctl -s status
|
||||
# error code 3 from pg_ctl means server is not running
|
||||
[[ "$?" -eq 3 ]]; return $?
|
||||
# 4 means there is no database in the data dir, this is okay
|
||||
[[ "$?" -eq 3 || "$?" -eq 4 ]]; return $?
|
||||
}
|
||||
|
||||
make_clean_db_dirs() {
|
||||
for dir in ("${data_dir}" "${tablespace_dir}"); do
|
||||
rm -rf "${dir}"
|
||||
${as_awips} mkdir -p "${dir}"
|
||||
${as_awips} chmod 700 "${dir}"
|
||||
done
|
||||
rm -rf "${data_dir}"
|
||||
${as_awips} mkdir -p "${data_dir}"
|
||||
${as_awips} chmod 700 "${data_dir}"
|
||||
rm -rf "${tablespace_dir}"
|
||||
${as_awips} mkdir -p "${tablespace_dir}"
|
||||
${as_awips} chmod 700 "${tablespace_dir}"
|
||||
}
|
||||
|
||||
restore_pg_hba() {
|
||||
if [[ -f "${hba_backup}" ]]; then
|
||||
log "INFO: Restoring backed up pg_hba.conf"
|
||||
${as_awips} mv "${hba_backup}" "${data_dir}"/pg_hba.conf
|
||||
${as_awips} cp -a "${hba_backup}" "${data_dir}"/pg_hba.conf
|
||||
${as_awips} chmod 600 "${data_dir}"/pg_hba.conf
|
||||
else
|
||||
log "WARN: No backed up pg_hba.conf to restore"
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -171,6 +192,7 @@ trap 'cleanup_exit' SIGINT SIGTERM
|
|||
|
||||
# Get certificates from master
|
||||
master_ssl_dir="${ssl_dir}/replication/${master_hostname}"
|
||||
echo ${as_awips} mkdir -p "${master_ssl_dir}"
|
||||
${as_awips} mkdir -p "${master_ssl_dir}"
|
||||
log "INFO: Downloading SSL certs and keyfile from ${master_hostname}"
|
||||
# must ssh as root to skip password prompt
|
||||
|
@ -184,6 +206,9 @@ find "${ssl_dir}"/replication -xdev -type d -exec chmod 700 {} \;
|
|||
# Backup pg_hba.conf
|
||||
if [[ -f "${data_dir}/pg_hba.conf" ]]; then
|
||||
${as_awips} cp -a "${data_dir}/pg_hba.conf" "${hba_backup}" || cleanup_exit
|
||||
log "INFO: Backup of pg_hba.conf is at ${hba_backup}"
|
||||
else
|
||||
log "WARN: Cannot backup local ${data_dir}/pg_hba.conf because it does not exist. Continuing anyway."
|
||||
fi
|
||||
|
||||
# Delete all database files
|
||||
|
@ -206,7 +231,11 @@ ${as_awips} "${pg_basebackup}" \
|
|||
--username="${db_rep_user}" \
|
||||
--port=${master_port} \
|
||||
--db="${ssl_part}" \
|
||||
-D "${data_tmpdir}" || cleanup_exit
|
||||
-D "${data_dir}" 2>&1 | tee -a ${log_file}
|
||||
|
||||
if [[ "${PIPESTATUS[0]}" != "0" ]]; then
|
||||
cleanup_exit
|
||||
fi
|
||||
|
||||
|
||||
# Write recovery.conf
|
||||
|
@ -248,4 +277,6 @@ if [[ "${is_recovery}" != "t" ]]; then
|
|||
cleanup_exit
|
||||
fi
|
||||
|
||||
rm -f "${hba_backup}"
|
||||
|
||||
log "INFO: Setup is complete. No errors reported."
|
||||
|
|
|
@ -177,9 +177,9 @@ public class SmartInitQueue {
|
|||
*
|
||||
* <pre>
|
||||
* Examples:
|
||||
* OAX_GRID_D2D_RUC13_20100923_0900 or
|
||||
* OAX_GRID_D2D_RUC13_20100923_0900:1 or
|
||||
* OAX_GRID_D2D_RUC13_20100923_0900:1:myRUC13
|
||||
* OAX_GRID_D2D_RAP13_20100923_0900 or
|
||||
* OAX_GRID_D2D_RAP13_20100923_0900:1 or
|
||||
* OAX_GRID_D2D_RAP13_20100923_0900:1:myRAP13
|
||||
* </pre>
|
||||
*/
|
||||
public void addManualInit(String init) {
|
||||
|
@ -290,9 +290,9 @@ public class SmartInitQueue {
|
|||
return rval;
|
||||
}
|
||||
|
||||
// OAX_GRID_D2D_RUC13_20100923_0900 or
|
||||
// OAX_GRID_D2D_RUC13_20100923_0900:1 or
|
||||
// OAX_GRID_D2D_RUC13_20100923_0900:1:myRUC13
|
||||
// OAX_GRID_D2D_RAP13_20100923_0900 or
|
||||
// OAX_GRID_D2D_RAP13_20100923_0900:1 or
|
||||
// OAX_GRID_D2D_RAP13_20100923_0900:1:myRAP13
|
||||
String[] tokens = initName.split("[:]");
|
||||
|
||||
int index = tokens[0].indexOf("_GRID_D2D_");
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
# 01/19/2015 #4014 dgilling Added ETSS.
|
||||
# 02/11/2015 #4053 rferrel Added GLWN and moved GLERL to display only for Great Lakes sites..
|
||||
# 01/19/2015 #4014 dgilling Added ETSS.
|
||||
# 02/24/2015 #16692 byin Added RTMA. Removed gfsLR and GWW233
|
||||
# 02/24/2015 #16692 byin Added RTMA. Removed gfsLR and WaveWatch
|
||||
# 03/19/2015 #4300 randerso Remove GUMa as it is obsolete (per Shannon White)
|
||||
# 03/30/2015 #17288 bhunder Added Guam-RTMA to D2D models
|
||||
# 03/30/2015 #17206 yteng Changed some parameters that are not rate parameters
|
||||
|
@ -102,8 +102,10 @@
|
|||
# 11/28/2017 6539 randerso Made P-ETSS and TPCSurgeProb elements D2DAccumulativeElements
|
||||
# 12/06/2017 DCS20267 psantos Add NWPS Rip Current Guidance
|
||||
# 12/20/2017 20510 ryu changes to StormTotalSnow parameter
|
||||
# 02/23/2018 #20395 wkwock Added NBM3.1 elements.
|
||||
# 04/03/2018 DR20656 arivera Missing comma: "Dune Erosion Probability" in optionalParmsDict['marine']
|
||||
# 05/09/2018 DR20715 arivera Missing comma: groups['marineSites'] after 'AVAK'
|
||||
# 06/18/2018 16729 ryu Remove tpHPC element from RFCQPF model and the smart init for the model.
|
||||
#
|
||||
####################################################################################################
|
||||
|
||||
|
@ -865,7 +867,7 @@ for r in siteRegion:
|
|||
myRegion=r
|
||||
break
|
||||
|
||||
groups['powt']=list(siteRegion['CR'])
|
||||
groups['powt']=list(groups['OCONUS_SITES']+ siteRegion['CR'] + siteRegion['ER'] + siteRegion['SR'] + siteRegion['WR'])
|
||||
groups['marineSites']=[
|
||||
# CONUS WFOs
|
||||
"CAR","GYX","BOX","OKX","PHI","LWX","AKQ","MHX","ILM","CHS",
|
||||
|
@ -1128,13 +1130,20 @@ PPI01=('PPI01', SCALAR, '%', '1-H Precip Potential Index', 100.0, 0.0, 0, NO)
|
|||
PPI06=('PPI06', SCALAR, '%', '6-H Precip Potential Index', 100.0, 0.0, 0, NO)
|
||||
PositiveEnergyAloft=("PositiveEnergyAloft" , SCALAR, "j/kg", "Positive energy aloft" , 500.0, 0.0, 1, NO)
|
||||
NegativeEnergyLowLevel=("NegativeEnergyLowLevel" , SCALAR, "j/kg", "Negative energy in the low levels" , 0.0, -500.0, 1, NO)
|
||||
PoTIP=('PotSleet', SCALAR, '%', 'Prob of Sleet', 100.0, 0.0, 0, NO)
|
||||
PoTR=('PotRain', SCALAR, '%', 'Prob of Rain', 100.0, 0.0, 0, NO)
|
||||
PoTS=('PotSnow', SCALAR, '%', 'Prob of Snow', 100.0, 0.0, 0, NO)
|
||||
PoTZR=('PotFreezingRain', SCALAR, '%', 'Prob of Freezing Rain', 100.0, 0.0, 0, NO)
|
||||
MaxTwAloft=("MaxTwAloft", SCALAR, 'C', 'Max Wet-Bulb Temp in Warm Nose', 40.0, -20.0, 1, NO)
|
||||
ProbIcePresent=("ProbIcePresent", SCALAR, "%", "Prob of Ice Present", 100.0, 0.0, 0, NO)
|
||||
ProbRefreezeSleet=("ProbRefreezeSleet", SCALAR, "%", "Prob of Refreeze into Sleet", 100.0, 0.0, 0, NO)
|
||||
SnowAmt01 = ("SnowAmt01", SCALAR, "in", "1-h Snow Accumulation", 20.0, 0.0, 1, YES)
|
||||
IceAccum01 = ("IceAccum01", SCALAR, "inch", "1-h Ice Accumulation", maxIceVal, 0.0, 3, NO)
|
||||
IceAccum = ("IceAccum", SCALAR, "inch", "6-h Ice Accumulation", 13.0, 0.0, 3, NO)
|
||||
TstmPrb1 = ("TstmPrb1", SCALAR, "%", "1-h SREF-based Prob. of a Thunderstorm", 100.0, 0.0, 0, NO)
|
||||
DryTstmPrb = ("DryTstmPrb", SCALAR, "%", "3-h SREF-based Prob. of a Dry Thunderstorm", 100.0, 0.0, 0, NO)
|
||||
WGS50pct =("WGS50pct", SCALAR, "kts", "10-m Wind Gust",125.0 , 0.0, 0, NO)
|
||||
WS50Prcntl30m =("WS50Prcntl30m", SCALAR, "kts", "30-m Wind Speed", 125.0, 0.0, 0, NO)
|
||||
WS50Prcntl80m =("WS50Prcntl80m", SCALAR, "kts", "80-m Wind Speed", 125.0, 0.0, 0, NO)
|
||||
Vis50pct =("Vis50pct", SCALAR, "SM", "Visibility",10.0 , 0.0, 3, NO)
|
||||
T50pct =("T50pct", SCALAR, "F", "Air Temperature", maxTempVal, minTempVal, 1, NO)
|
||||
PMSL10pct =("PMSL10pct", SCALAR, "mb", "10th percentile Mean Sea Level Pressure", 1100.0, 900.0, 1, NO)
|
||||
PMSL50pct =("PMSL50pct", SCALAR, "mb", "50th percentile Mean Sea Level Pressure", 1100.0, 900.0, 1, NO)
|
||||
PMSL90pct =("PMSL90pct", SCALAR, "mb", "90th percentile Mean Sea Level Pressure", 1100.0, 900.0, 1, NO)
|
||||
FosBerg = ("FosBerg", SCALAR, "none", "Fosberg Fire Weather Index", 100.0, 0.0, 0, NO)
|
||||
|
||||
|
||||
|
||||
|
@ -2368,8 +2377,8 @@ else:
|
|||
#---------------------------------------------------------------------------
|
||||
# base urls for the ISC Routing Table
|
||||
ISC_ROUTING_TABLE_ADDRESS = {
|
||||
"ANCF" : "http://localhost:8080/irt",
|
||||
"BNCF" : "http://localhost:8080/irt"
|
||||
"ANCF" : "http://svcbu-ancf.er.awips.noaa.gov:8080/irt",
|
||||
"BNCF" : "http://svcbu-bncf.er.awips.noaa.gov:8080/irt"
|
||||
}
|
||||
|
||||
|
||||
|
@ -2685,7 +2694,7 @@ for s in ['ALR', 'FWR', 'KRF', 'MSR', 'ORN', 'PTR', 'RHA', 'RSA', 'STR', 'TAR',
|
|||
modelDict['FFG'+s] = {'D2DMODELS': 'FFG-'+s}
|
||||
|
||||
modelDict['GFS20'] = {
|
||||
'D2DMODELS': 'GFS215',
|
||||
'D2DMODELS': 'GFS20',
|
||||
'D2DAccumulativeElements': ['tp3hr','tp6hr', 'tp', 'cp', 'crain', 'csnow', 'cfrzr', 'cicep'],
|
||||
'DB': ('GFS20', 'GRID', '', NO, NO, 2, 0),
|
||||
'Parms': [([Wetflag], FireWx1300TC),
|
||||
|
@ -2723,8 +2732,8 @@ modelDict['GWW'] = {
|
|||
],
|
||||
}
|
||||
|
||||
modelDict['GWW233'] = {
|
||||
'D2DMODELS': 'GWW233',}
|
||||
modelDict['WaveWatch'] = {
|
||||
'D2DMODELS': 'WaveWatch',}
|
||||
|
||||
modelDict['GlobalWave'] = {
|
||||
'D2DMODELS': 'GlobalWave',
|
||||
|
@ -2838,7 +2847,7 @@ modelDict['NAHwave4'] = {
|
|||
|
||||
modelDict['NAM12'] = {
|
||||
'D2DAccumulativeElements': ['tp', 'cp', 'crain', 'csnow', 'cfrzr', 'cicep'],
|
||||
'D2DMODELS': 'ETA218',
|
||||
'D2DMODELS': 'NAM12',
|
||||
'DB': ('NAM12', 'GRID', '', NO, NO, 2, 0),
|
||||
'INITMODULES': 'NAM12',
|
||||
'Parms': STD3_MODEL,
|
||||
|
@ -2846,11 +2855,11 @@ modelDict['NAM12'] = {
|
|||
|
||||
modelDict['NAM20'] = {
|
||||
'D2DAccumulativeElements': ['tp', 'cp'],
|
||||
'D2DMODELS': 'mesoEta215',}
|
||||
'D2DMODELS': 'NAM20',}
|
||||
|
||||
modelDict['NAM40'] = {
|
||||
'D2DAccumulativeElements': ['tp', 'cp'],
|
||||
'D2DMODELS': 'mesoEta212',
|
||||
'D2DMODELS': 'NAM40',
|
||||
'DB': ('NAM40', 'GRID', '', NO, NO, 2, 0),
|
||||
'Parms': STD3_MODEL,
|
||||
}
|
||||
|
@ -2882,7 +2891,9 @@ modelDict['NamDNG'] = {
|
|||
}
|
||||
|
||||
modelDict['NationalBlend'] = {
|
||||
'D2DAccumulativeElements': ["pop12hr", "pop", "pop6hr", "tp", "ppi1hr", "ppi6hr", "tp1hr", "tp6hr", "thp3hr", "thp6hr"],
|
||||
'D2DAccumulativeElements': ["pop12hr", "pop", "pop6hr", "tp", "ppi1hr", "ppi6hr",
|
||||
"tp1hr", "tp6hr", "thp3hr", "thp6hr",
|
||||
"totsn1hr", "totsn6hr", "ficeac1hr", "ficeac6hr"],
|
||||
'D2DMODELS': 'NationalBlend',
|
||||
'DB': ('NationalBlend', 'GRID', '', NO, NO, 7, 0),
|
||||
'INITMODULES': 'NationalBlend',
|
||||
|
@ -2890,11 +2901,24 @@ modelDict['NationalBlend'] = {
|
|||
([QPF1,PPI01,CloudBasePrimary,Ceiling,Visibility],TC1),
|
||||
([PoTIP, PoTR, PoTRW, PoTS, PoTSW, PoTZR,],TC1),
|
||||
([SnowLevel,MaxTwAloft,ProbIcePresent, ProbRefreezeSleet,SnowRatio],TC1),
|
||||
([PositiveEnergyAloft,NegativeEnergyLowLevel],TC1),
|
||||
([TstmPrb3],TC3NG),
|
||||
([TstmPrb6,QPF,PoP6,PPI06],TC6NG),
|
||||
([PositiveEnergyAloft, NegativeEnergyLowLevel],TC1),
|
||||
([MixHgt, TransWind, LLWS, VentRate, LLWSHgt, Radar,
|
||||
SigWaveHgt, Weather, Haines, FosBerg,
|
||||
SnowAmt01, IceAccum01, TstmPrb1],TC1),
|
||||
([TstmPrb3, DryTstmPrb],TC3NG),
|
||||
([TstmPrb6, QPF, PoP6, PPI06, SnowAmt, IceAccum,
|
||||
QPF10Prcntl, QPF50Prcntl, QPF90Prcntl],TC6NG),
|
||||
([MaxT], MaxTTC), ([MinT], MinTTC),
|
||||
([MaxRH], MaxRHTC), ([MinRH], MinRHTC),([PoP],TC12NG),
|
||||
([MaxRH], MaxRHTC), ([MinRH], MinRHTC),([PoP, TstmPrb12],TC12NG),
|
||||
],
|
||||
}
|
||||
|
||||
modelDict['NationalBlendOC'] = {
|
||||
'D2DMODELS': 'NationalBlendOC',
|
||||
'DB': ('NationalBlend', 'GRID', '', NO, NO, 2, 0),
|
||||
'INITMODULES': 'NationalBlendOC',
|
||||
'Parms': [([WGS50pct, WS50Prcntl30m, WS50Prcntl80m, Vis50pct, T50pct,
|
||||
PMSL10pct, PMSL50pct, PMSL90pct], TC1),
|
||||
],
|
||||
}
|
||||
|
||||
|
@ -2908,10 +2932,8 @@ modelDict['PWPF'] = {
|
|||
'D2DMODELS': 'PWPF',}
|
||||
|
||||
modelDict['RFCQPF'] = {
|
||||
'D2DAccumulativeElements': ['tpHPC'],
|
||||
'D2DMODELS': 'RFCqpf',
|
||||
'DB': ('RFCQPF', 'GRID', '', NO, NO, 4, 0),
|
||||
'INITMODULES': 'RFCQPF',
|
||||
'Parms': [([QPF], TC6NG),
|
||||
],
|
||||
}
|
||||
|
@ -2924,11 +2946,11 @@ modelDict['RTMA'] = {
|
|||
'Parms': RTMAPARMS,
|
||||
}
|
||||
|
||||
modelDict['RUC13'] = {
|
||||
modelDict['RAP13'] = {
|
||||
'D2DAccumulativeElements': ['tp', 'cp'],
|
||||
'D2DMODELS': 'RUC130',
|
||||
'DB': ('RUC13', 'GRID', '', NO, NO, 2, 0),
|
||||
'INITMODULES': 'RUC13',
|
||||
'D2DMODELS': 'RAP13',
|
||||
'DB': ('RAP13', 'GRID', '', NO, NO, 2, 0),
|
||||
'INITMODULES': 'RAP13',
|
||||
'INITSKIPS': [1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23],
|
||||
'Parms': STD1_MODEL,
|
||||
}
|
||||
|
@ -3178,11 +3200,11 @@ if SID in groups['ALASKA_SITES']:
|
|||
|
||||
updateModelDict(modelDict,'ESTOFS','D2DMODELS', 'estofsAK')
|
||||
updateModelDict(modelDict,'ETSS','D2DMODELS', 'ETSS-AK')
|
||||
updateModelDict(modelDict,'GFS20','D2DMODELS', 'GFS217')
|
||||
updateModelDict(modelDict,'GFS20','D2DMODELS', 'AK-GFS22')
|
||||
updateModelDict(modelDict,'HIRESWarw','D2DMODELS', 'HiResW-ARW-AK')
|
||||
updateModelDict(modelDict,'HIRESWnmm','D2DMODELS', 'HiResW-NMM-AK')
|
||||
updateModelDict(modelDict,'MOSGuide','D2DMODELS', 'MOSGuide-AK')
|
||||
updateModelDict(modelDict,'NAM12','D2DMODELS', 'ETA242')
|
||||
updateModelDict(modelDict,'NAM12','D2DMODELS', 'AK-NAM11')
|
||||
updateModelDict(modelDict,'NamDNG','D2DMODELS', 'AK-NamDNG3')
|
||||
updateModelDict(modelDict,'NationalBlend','D2DMODELS', 'NationalBlendAK')
|
||||
updateModelDict(modelDict,'RTMA','D2DMODELS', 'AK-RTMA3')
|
||||
|
@ -3213,7 +3235,7 @@ elif SID == "HFO":
|
|||
'Parms': STD6_MODEL,
|
||||
}
|
||||
|
||||
updateModelDict(modelDict,'GWW233','D2DMODELS', 'GWW233')
|
||||
updateModelDict(modelDict,'WaveWatch','D2DMODELS', 'WaveWatch')
|
||||
updateModelDict(modelDict,'GlobalWave','D2DMODELS', 'GlobalWave')
|
||||
updateModelDict(modelDict,'RTMA','D2DMODELS', 'HI-RTMA')
|
||||
updateModelDict(modelDict,'NamDNG','D2DMODELS', 'HI-NamDNG5')
|
||||
|
@ -3228,7 +3250,7 @@ elif SID == "HFO":
|
|||
updateModelDict(modelDict,'MOSGuide','D2DMODELS', 'MOSGuide-HI')
|
||||
updateModelDict(modelDict,'NationalBlend','D2DMODELS', 'NationalBlendHI')
|
||||
# Model databases for HFO
|
||||
includeOnly = ['ECMWFHiRes', 'ESTOFS', 'GFS75', 'GWW233', 'GlobalWave',
|
||||
includeOnly = ['ECMWFHiRes', 'ESTOFS', 'GFS75', 'WaveWatch', 'GlobalWave',
|
||||
'HIRESWarw', 'HIRESWnmm', 'MOSGuide', 'NamDNG', 'NationalBlend',
|
||||
'RTMA', 'RTOFS-Honolulu', 'SPC', 'TPCProb', 'TPCProbPrelim', 'nwpsCG1GUM',
|
||||
'nwpsCG1HFO', 'nwpsTrkngCG0GUM', 'nwpsTrkngCG0HFO',
|
||||
|
@ -3259,7 +3281,7 @@ elif SID == "GUM":
|
|||
elif SID == "SJU":
|
||||
updateModelDict(modelDict,'GFS80','D2DMODELS', 'AVN211')
|
||||
updateModelDict(modelDict,'NAM80','D2DMODELS', 'ETA')
|
||||
updateModelDict(modelDict,'GWW233','D2DMODELS', 'GWW233')
|
||||
updateModelDict(modelDict,'WaveWatch','D2DMODELS', 'WaveWatch')
|
||||
updateModelDict(modelDict,'GlobalWave','D2DMODELS', 'GlobalWave')
|
||||
updateModelDict(modelDict,'WNAwave10','D2DMODELS', 'WNAwave10')
|
||||
updateModelDict(modelDict,'WNAwave4','D2DMODELS', 'WNAwave4')
|
||||
|
@ -3273,10 +3295,10 @@ elif SID == "SJU":
|
|||
updateModelDict(modelDict,'RTOFS-Atlantic','D2DMODELS', 'RTOFS-Atlantic')
|
||||
updateModelDict(modelDict,'ESTOFS','D2DMODELS', 'estofsPR')
|
||||
updateModelDict(modelDict,'NAHwave4','D2DMODELS', 'NAHwave4')
|
||||
updateModelDict(modelDict,'GFS20','D2DMODELS', 'GFS20-PRICO')
|
||||
updateModelDict(modelDict,'GFS20','D2DMODELS', 'PR-GFS')
|
||||
updateModelDict(modelDict,'NationalBlend','D2DMODELS', 'NationalBlendPR')
|
||||
# Model databases for SJU
|
||||
includeOnly = ['ECMWFHiRes', 'ESTOFS', 'GFS20', 'GFS80', 'GWW233',
|
||||
includeOnly = ['ECMWFHiRes', 'ESTOFS', 'GFS20', 'GFS80', 'WaveWatch',
|
||||
'GlobalWave', 'HIRESWarw', 'HIRESWnmm', 'NAHwave4', 'NAM80',
|
||||
'NationalBlend', 'RTMA', 'RTOFS-Atlantic', 'SPC', 'TPCProb',
|
||||
'TPCProbPrelim', 'WNAwave10', 'WNAwave4',
|
||||
|
|
|
@ -25,6 +25,13 @@
|
|||
# Configuration Guides->Smart Initialization Configuration section of the GFE
|
||||
# Online Help for guidance on creating a new smart init
|
||||
##
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
#
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 02/23/2018 #20395 wkwock Added NBM3.1 elements.
|
||||
|
||||
from numpy import *
|
||||
|
||||
|
@ -276,7 +283,7 @@ class NationalBlendForecaster(Forecaster):
|
|||
# values.
|
||||
CloudBasePrimary = where(less(CloudBasePrimary, 0), 250, CloudBasePrimary)
|
||||
|
||||
return self.smoothpm(CloudBasePrimary, 3)
|
||||
return CloudBasePrimary
|
||||
|
||||
def calcMaxRH(self, MAXRH12hr_FHAG2):
|
||||
return MAXRH12hr_FHAG2
|
||||
|
@ -287,8 +294,8 @@ class NationalBlendForecaster(Forecaster):
|
|||
#===========================================================================
|
||||
# Calc MaxTwAloft - Convert K to C
|
||||
#===========================================================================
|
||||
def calcMaxTwAloft(self, MaxTW_EA):
|
||||
return (MaxTW_EA - 273.15)
|
||||
def calcMaxTwAloft(self, maxtw_FHAG61040000):
|
||||
return (maxtw_FHAG61040000 - 273.15)
|
||||
|
||||
def calcMinRH(self, MINRH12hr_FHAG2):
|
||||
return MINRH12hr_FHAG2
|
||||
|
@ -299,14 +306,14 @@ class NationalBlendForecaster(Forecaster):
|
|||
#===========================================================================
|
||||
# NegativeEnergyLowLevel
|
||||
#===========================================================================
|
||||
def calcNegativeEnergyLowLevel(self, nbe_EA):
|
||||
return nbe_EA
|
||||
def calcNegativeEnergyLowLevel(self, nbe_SFC):
|
||||
return nbe_SFC
|
||||
|
||||
#===========================================================================
|
||||
# Positive Energy Aloft
|
||||
#===========================================================================
|
||||
def calcPositiveEnergyAloft(self, pbe_EA):
|
||||
return pbe_EA
|
||||
def calcPositiveEnergyAloft(self, pbe_FHAG61040000):
|
||||
return pbe_FHAG61040000
|
||||
|
||||
def calcPoP(self, pop_SFC):
|
||||
return pop_SFC
|
||||
|
@ -421,6 +428,395 @@ class NationalBlendForecaster(Forecaster):
|
|||
def calcPotFreezingRain(self, ptypfreezingrain_SFC):
|
||||
return(ptypfreezingrain_SFC)
|
||||
|
||||
def calcTransWind(self, trwspd_EA, trwdir_EA):
|
||||
newmag=self.convertMsecToKts(trwspd_EA)
|
||||
return (newmag, trwdir_EA)
|
||||
|
||||
def calcLLWS(self, wind_FHAG0610):
|
||||
mag, dir = wind_FHAG0610
|
||||
Mask = mag >= 150
|
||||
mag = self.convertMsecToKts(mag) # convert to knots from m/s
|
||||
mag[Mask] = 0
|
||||
dir[Mask] = 0
|
||||
return (mag, dir)
|
||||
|
||||
def calcSnowAmt(self, totsn6hr_SFC):
|
||||
return (totsn6hr_SFC * 1000) / 25.4
|
||||
|
||||
def calcMixHgt(self, mixht_EA):
|
||||
return mixht_EA / 0.3048
|
||||
|
||||
def calcVentRate(self, vrate_EA):
|
||||
return vrate_EA
|
||||
|
||||
def calcHaines(self, hindex6hr_EA):
|
||||
return hindex6hr_EA
|
||||
|
||||
def calcFosBerg(self, fosindx6hr_SFC):
|
||||
return fosindx6hr_SFC
|
||||
|
||||
def calcLLWSHgt(self, llwshgt_FHAG0610):
|
||||
return llwshgt_FHAG0610 * 32.808398951
|
||||
|
||||
def calcRadar(self, maxref1hr_FHAG1000):
|
||||
return maxref1hr_FHAG1000
|
||||
|
||||
def calcSigWaveHgt(self, htsgw_SFC):
|
||||
return htsgw_SFC / 0.3048
|
||||
|
||||
def calcWx(self, pwther_SFC):
|
||||
#https://graphical.weather.gov/definitions/defineWx.html
|
||||
wx = pwther_SFC.astype(int8)
|
||||
outOfAreaMask = logical_or(greater(wx, 7),less(wx, 0))
|
||||
wx[outOfAreaMask] = 0
|
||||
|
||||
wxtypes = ["<NoCov>:<NoWx>:<NoInten>:<NoVis>:",
|
||||
"Chc:R:-:<NoVis>:",
|
||||
"SChc:R:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:",
|
||||
"SChc:R:m:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:",
|
||||
"Chc:R:+:<NoVis>:",
|
||||
"Iso:T:<NoInten>:<NoVis>:^SChc:RW:-:<NoVis>:",
|
||||
"Chc:RW:-:<NoVis>:^Iso:T:<NoInten>:<NoVis>:",
|
||||
"Chc:RW:-:<NoVis>:^Sct:T:<NoInten>:<NoVis>:",
|
||||
"SChc:S:-:<NoVis>:^SChc:R:-:<NoVis>:",
|
||||
"Chc:S:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"SChc:S:-:<NoVis>:",
|
||||
"SChc:R:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Chc:S:-:<NoVis>:",
|
||||
"Chc:R:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:^Lkly:R:-:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:",
|
||||
"Lkly:S:m:<NoVis>:",
|
||||
"Lkly:S:m:<NoVis>:^Lkly:R:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Def:R:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Lkly:S:-:<NoVis>:",
|
||||
"Def:S:m:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Lkly:S:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^SChc:R:-:<NoVis>:",
|
||||
"Chc:S:m:<NoVis>:",
|
||||
"SChc:S:m:<NoVis>:",
|
||||
"Def:S:+:<NoVis>:",
|
||||
"Lkly:S:+:<NoVis>:",
|
||||
"Chc:R:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Def:S:+:<NoVis>:^Def:R:+:<NoVis>:",
|
||||
"Def:S:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"Lkly:S:m:<NoVis>:^SChc:R:m:<NoVis>:",
|
||||
"Def:S:m:<NoVis>:^Def:R:m:<NoVis>:",
|
||||
"Def:S:m:<NoVis>:^Chc:ZR:m:<NoVis>:",
|
||||
"Lkly:S:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:^SChc:R:-:<NoVis>:",
|
||||
"Def:S:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Def:S:m:<NoVis>:^SChc:R:m:<NoVis>:",
|
||||
"Chc:S:-:<NoVis>:^SChc:R:-:<NoVis>:",
|
||||
"Lkly:RW:-:<NoVis>:^Iso:T:<NoInten>:<NoVis>:",
|
||||
"Chc:S:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Lkly:S:+:<NoVis>:^Lkly:R:+:<NoVis>:",
|
||||
"Lkly:RW:-:<NoVis>:^Sct:T:<NoInten>:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"Chc:S:+:<NoVis>:",
|
||||
"Chc:S:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Lkly:S:m:<NoVis>:^Chc:ZR:m:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Chc:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"SChc:S:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"SChc:ZR:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"SChc:ZR:-:<NoVis>:",
|
||||
"Def:RW:-:<NoVis>:^Iso:T:<NoInten>:<NoVis>:",
|
||||
"SChc:S:m:<NoVis>:^SChc:R:m:<NoVis>:",
|
||||
"Chc:RW:m:<NoVis>:^Iso:T:<NoInten>:<NoVis>:",
|
||||
"Lkly:RW:m:<NoVis>:^Iso:T:<NoInten>:<NoVis>:",
|
||||
"Chc:RW:m:<NoVis>:^Sct:T:<NoInten>:<NoVis>:",
|
||||
"Lkly:RW:m:<NoVis>:^Sct:T:<NoInten>:<NoVis>:",
|
||||
"Def:RW:-:<NoVis>:^Sct:T:<NoInten>:<NoVis>:",
|
||||
"Def:RW:m:<NoVis>:^Sct:T:<NoInten>:<NoVis>:",
|
||||
"Def:RW:m:<NoVis>:^Iso:T:<NoInten>:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Lkly:R:-:<NoVis>:",
|
||||
"Chc:S:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Def:S:+:<NoVis>:^Chc:ZR:+:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:^Lkly:ZR:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^Lkly:S:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Lkly:S:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Lkly:ZR:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Def:S:-:<NoVis>:",
|
||||
"Lkly:S:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"SChc:IP:-:<NoVis>:^SChc:S:-:<NoVis>:^SChc:R:-:<NoVis>:",
|
||||
"Chc:IP:-:<NoVis>:^Chc:S:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"Def:S:+:<NoVis>:^Chc:R:+:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Lkly:S:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Lkly:S:m:<NoVis>:",
|
||||
"Def:RW:+:<NoVis>:^Iso:T:<NoInten>:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^SChc:S:m:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Chc:R:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Chc:R:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Chc:R:-:<NoVis>:^SChc:IP:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^SChc:IP:+:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^SChc:IP:+:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^SChc:ZR:+:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Chc:ZR:m:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^Chc:ZR:+:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Chc:IP:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^Chc:IP:+:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^Chc:IP:+:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Chc:IP:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:ZR:m:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^Chc:IP:+:<NoVis>:^SChc:ZR:+:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^Chc:IP:+:<NoVis>:^SChc:ZR:+:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^SChc:IP:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^SChc:IP:+:<NoVis>:^SChc:ZR:+:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^SChc:ZR:+:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:ZR:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^SChc:IP:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^SChc:ZR:+:<NoVis>:^SChc:IP:+:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^SChc:ZR:+:<NoVis>:^SChc:IP:+:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^Chc:ZR:+:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Lkly:IP:m:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^SChc:IP:+:<NoVis>:^SChc:ZR:+:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^Chc:ZR:+:<NoVis>:^SChc:IP:+:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^Chc:ZR:+:<NoVis>:^SChc:IP:+:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^SChc:ZR:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^Chc:IP:+:<NoVis>:^Chc:ZR:+:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^Chc:IP:+:<NoVis>:^Chc:ZR:+:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Chc:ZR:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^Lkly:IP:+:<NoVis>:^SChc:ZR:+:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Lkly:IP:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^Lkly:IP:+:<NoVis>:^SChc:ZR:+:<NoVis>:",
|
||||
"Def:R:+:<NoVis>:^Lkly:IP:+:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Lkly:IP:m:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^Lkly:R:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Lkly:IP:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Lkly:R:+:<NoVis>:^Lkly:IP:+:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Lkly:IP:m:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^Lkly:R:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Def:R:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^Lkly:ZR:-:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Lkly:ZR:+:<NoVis>:^Chc:R:+:<NoVis>:",
|
||||
"Chc:S:+:<NoVis>:^Chc:R:+:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Chc:IP:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^SChc:R:m:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Chc:S:m:<NoVis>:^SChc:R:m:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^SChc:IP:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Chc:ZR:m:<NoVis>:^SChc:R:m:<NoVis>:",
|
||||
"Chc:ZR:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^Chc:ZR:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^SChc:ZR:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^SChc:ZR:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^SChc:IP:m:<NoVis>:^SChc:S:m:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^SChc:IP:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^SChc:IP:m:<NoVis>:^SChc:S:m:<NoVis>:",
|
||||
"Chc:ZR:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^Chc:IP:m:<NoVis>:^SChc:ZR:m:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^SChc:S:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^SChc:S:m:<NoVis>:",
|
||||
"Chc:ZR:m:<NoVis>:^SChc:S:m:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:S:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Chc:ZR:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^Chc:ZR:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Chc:S:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Chc:ZR:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:R:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^SChc:R:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:S:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Chc:S:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^Lkly:R:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Lkly:IP:m:<NoVis>:^Chc:ZR:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:R:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Chc:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^SChc:IP:m:<NoVis>:^SChc:S:m:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Lkly:S:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^SChc:ZR:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^SChc:S:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^SChc:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^SChc:IP:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^SChc:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Lkly:S:m:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^Chc:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Lkly:IP:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Chc:ZR:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Chc:R:m:<NoVis>:^Chc:IP:m:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Lkly:ZR:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Def:IP:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Lkly:IP:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:^Chc:IP:m:<NoVis>:^SChc:R:m:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Chc:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Chc:ZR:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Chc:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^SChc:IP:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Chc:R:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:^Lkly:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Lkly:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Def:ZR:-:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:R:m:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Chc:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^Chc:R:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Chc:R:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Chc:R:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Chc:ZR:m:<NoVis>:^Chc:IP:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Chc:IP:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Chc:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Chc:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Chc:R:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Chc:IP:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^SChc:S:m:<NoVis>:",
|
||||
"Chc:ZR:m:<NoVis>:^Chc:S:m:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^Chc:R:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^SChc:ZR:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Chc:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Lkly:IP:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Lkly:IP:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Lkly:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Def:IP:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Def:R:m:<NoVis>:^Lkly:IP:m:<NoVis>:^Lkly:S:m:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Lkly:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Lkly:R:m:<NoVis>:^Lkly:IP:m:<NoVis>:^Lkly:S:m:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Def:S:-:<NoVis>:^Def:R:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Chc:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Lkly:IP:-:<NoVis>:^Lkly:S:-:<NoVis>:^Lkly:R:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Def:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^SChc:IP:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Lkly:IP:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Def:R:-:<NoVis>:^Chc:IP:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^SChc:R:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Def:ZR:m:<NoVis>:^Def:IP:m:<NoVis>:^Def:S:m:<NoVis>:",
|
||||
"Def:S:m:<NoVis>:^SChc:IP:m:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Def:R:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Lkly:S:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Def:S:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Lkly:IP:-:<NoVis>:",
|
||||
"Lkly:ZR:m:<NoVis>:",
|
||||
"Def:IP:-:<NoVis>:^Def:S:-:<NoVis>:^Lkly:ZR:-:<NoVis>:",
|
||||
"Def:S:-:<NoVis>:^Lkly:ZR:-:<NoVis>:^Lkly:IP:-:<NoVis>:",
|
||||
"Chc:R:-:<NoVis>:^SChc:ZR:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Def:ZR:-:<NoVis>:^Lkly:IP:-:<NoVis>:^Lkly:S:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^Lkly:IP:-:<NoVis>:^Lkly:S:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^SChc:R:-:<NoVis>:",
|
||||
"Lkly:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^Chc:R:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^SChc:R:-:<NoVis>:",
|
||||
"Chc:R:-:<NoVis>:^Chc:IP:-:<NoVis>:^Chc:S:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Chc:R:-:<NoVis>:^Chc:ZR:-:<NoVis>:",
|
||||
"Lkly:R:-:<NoVis>:^Lkly:IP:-:<NoVis>:^Lkly:S:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^Chc:S:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Chc:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Chc:S:-:<NoVis>:^Chc:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^Chc:S:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:^SChc:S:-:<NoVis>:^SChc:IP:-:<NoVis>:",
|
||||
"Def:S:+:<NoVis>:^SChc:ZR:+:<NoVis>:",
|
||||
"SChc:R:-:<NoVis>:^SChc:IP:-:<NoVis>:^SChc:S:-:<NoVis>:",
|
||||
]
|
||||
|
||||
|
||||
return (wx, wxtypes)
|
||||
|
||||
def calcSnowAmt01(self, totsn1hr_SFC):
|
||||
return (totsn1hr_SFC * 1000) / 25.4
|
||||
|
||||
def calcIceAccum01(self, ficeac1hr_SFC):
|
||||
return (ficeac1hr_SFC * 1000) / 25.4
|
||||
|
||||
def calcIceAccum(self, ficeac6hr_SFC):
|
||||
return (ficeac6hr_SFC * 1000) / 25.4
|
||||
|
||||
def calcQPF10Prcntl(self, tp10pct6hr_SFC):
|
||||
return tp10pct6hr_SFC / 25.4
|
||||
|
||||
def calcQPF50Prcntl(self, tp50pct6hr_SFC):
|
||||
return tp50pct6hr_SFC / 25.4
|
||||
|
||||
def calcQPF90Prcntl(self, tp90pct6hr_SFC):
|
||||
return tp90pct6hr_SFC / 25.4
|
||||
|
||||
def calcTstmPrb1(self, thp1hr_SFC):
|
||||
return thp1hr_SFC
|
||||
|
||||
def calcDryTstmPrb(self, drytpprob3hr_SFC):
|
||||
return drytpprob3hr_SFC
|
||||
|
||||
def calcTstmPrb12(self, thp12hr_SFC):
|
||||
return thp12hr_SFC
|
||||
|
||||
def main():
|
||||
NationalBlendForecaster().run()
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
##
|
||||
#This software was developed and / or modified by NOAA/NWS/OCP/ASDT##
|
||||
|
||||
##
|
||||
# This is a base file that is not intended to be overridden.
|
||||
#
|
||||
# This file can be subclassed to override behavior. Please see the
|
||||
# Configuration Guides->Smart Initialization Configuration section of the GFE
|
||||
# Online Help for guidance on creating a new smart init
|
||||
##
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# SOFTWARE HISTORY
|
||||
#
|
||||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 02/23/2018 #20395 wkwock Added NBM3.1 elements.
|
||||
|
||||
from Init import *
|
||||
|
||||
##--------------------------------------------------------------------------
|
||||
## Module that calculates surface weather elements from SPC model
|
||||
## output.
|
||||
##
|
||||
##--------------------------------------------------------------------------
|
||||
class NationalBlendOCForecaster(Forecaster):
|
||||
def __init__(self):
|
||||
Forecaster.__init__(self, "NationalBlendOC", "NationalBlend")
|
||||
|
||||
def calcWGS50pct(self, wgs50pct_FHAG10):
|
||||
return wgs50pct_FHAG10
|
||||
|
||||
def calcWS50Prcntl30m(self, ws50pct_FHAG30):
|
||||
return ws50pct_FHAG30
|
||||
|
||||
def calcWS50Prcntl80m(self, ws50pct_FHAG80):
|
||||
return ws50pct_FHAG80
|
||||
|
||||
def calcVis50pct(self, vis50pct_SFC):
|
||||
return self.convertMtoSM(vis50pct_SFC)
|
||||
|
||||
def calcT50pct(self, t50pct_FHAG2):
|
||||
return self.convertKtoF(t50pct_FHAG2)
|
||||
|
||||
def calcPMSL10pct(self, pmsl10pct_MSL):
|
||||
return pmsl10pct_MSL / 100.0
|
||||
|
||||
def calcPMSL50pct(self, pmsl50pct_MSL):
|
||||
return pmsl50pct_MSL / 100.0
|
||||
|
||||
def calcPMSL90pct(self, pmsl90pct_MSL):
|
||||
return pmsl90pct_MSL / 100.0
|
||||
|
||||
def windChillCalc(self, T, Wind):
|
||||
mag = Wind[0] * 1.15077945
|
||||
WindChill = where(less_equal(mag, 1), T, 35.74 + (0.6215 * T) - (35.75 * (mag ** 0.16)) + (0.4275 * T * (mag ** 0.16)))
|
||||
|
||||
# clip values where WindChill > T
|
||||
WindChill = where(greater(WindChill, T), T, WindChill)
|
||||
|
||||
# substitute the temperature if WindChill >= 51 degrees
|
||||
WindChill = where(greater_equal(T, 51), T, WindChill)
|
||||
return WindChill
|
||||
|
||||
|
||||
def main():
|
||||
NationalBlendOCForecaster().run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -17,6 +17,15 @@
|
|||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
# further licensing information.
|
||||
##
|
||||
|
||||
##
|
||||
# This is a base file that is not intended to be overridden.
|
||||
#
|
||||
# This file can be subclassed to override behavior. Please see the
|
||||
# Configuration Guides->Smart Initialization Configuration section of the GFE
|
||||
# Online Help for guidance on creating a new smart init
|
||||
##
|
||||
|
||||
from Init import *
|
||||
|
||||
##--------------------------------------------------------------------------
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
|
||||
from Init import *
|
||||
##--------------------------------------------------------------------------
|
||||
## Module that calculates surface weather elements from RUC80 model
|
||||
## Module that calculates surface weather elements from RAP40 model
|
||||
## output.
|
||||
##
|
||||
##--------------------------------------------------------------------------
|
||||
class RUC80Forecaster(Forecaster):
|
||||
class RAP40Forecaster(Forecaster):
|
||||
def __init__(self):
|
||||
Forecaster.__init__(self, "RUC80")
|
||||
Forecaster.__init__(self, "RAP40")
|
||||
|
||||
##--------------------------------------------------------------------------
|
||||
## These levels will be used to create vertical soundings. These are
|
||||
|
@ -531,4 +531,4 @@ class RUC80Forecaster(Forecaster):
|
|||
return lal
|
||||
|
||||
def main():
|
||||
RUC80Forecaster().run()
|
||||
RAP40Forecaster().run()
|
|
@ -1,559 +0,0 @@
|
|||
##
|
||||
# This software was developed and / or modified by Raytheon Company,
|
||||
# pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
#
|
||||
# U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
# This software product contains export-restricted data whose
|
||||
# export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
# to non-U.S. persons whether in the United States or abroad requires
|
||||
# an export license or other authorization.
|
||||
#
|
||||
# Contractor Name: Raytheon Company
|
||||
# Contractor Address: 6825 Pine Street, Suite 340
|
||||
# Mail Stop B8
|
||||
# Omaha, NE 68106
|
||||
# 402.291.0100
|
||||
#
|
||||
# See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
# further licensing information.
|
||||
##
|
||||
|
||||
##
|
||||
# This is a base file that is not intended to be overridden.
|
||||
#
|
||||
# This file can be subclassed to override behavior. Please see the
|
||||
# Configuration Guides->Smart Initialization Configuration section of the GFE
|
||||
# Online Help for guidance on creating a new smart init
|
||||
##
|
||||
|
||||
from Init import *
|
||||
|
||||
##--------------------------------------------------------------------------
|
||||
## Module that calculates surface weather elements from RUC13 model
|
||||
## output.
|
||||
##
|
||||
##--------------------------------------------------------------------------
|
||||
class RUC13Forecaster(Forecaster):
|
||||
def __init__(self):
|
||||
Forecaster.__init__(self, "RUC13")
|
||||
|
||||
##--------------------------------------------------------------------------
|
||||
## These levels will be used to create vertical soundings. These are
|
||||
## defined here since they are model dependent.
|
||||
##--------------------------------------------------------------------------
|
||||
def levels(self):
|
||||
return ["MB1000", "MB950", "MB900", "MB850", "MB800", "MB750", "MB700",
|
||||
"MB650", "MB600", "MB550", "MB500", "MB450", "MB400",
|
||||
"MB350", "MB300"]
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Returns the maximum of the specified MaxT and the T grids
|
||||
##--------------------------------------------------------------------------
|
||||
def calcMaxT(self, T, MaxT):
|
||||
if MaxT is None:
|
||||
return T
|
||||
return maximum(MaxT, T)
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Returns the minimum of the specified MinT and T grids
|
||||
##--------------------------------------------------------------------------
|
||||
def calcMinT(self, T, MinT):
|
||||
if MinT is None:
|
||||
return T
|
||||
return minimum(MinT, T)
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates the temperature at the elevation indicated in the topo
|
||||
## grid. This tool simply interpolates the temperature value from
|
||||
## model's isobaric temperature cube.
|
||||
##-------------------------------------------------------------------------
|
||||
def calcT(self, t_FHAG2, t_BL030, t_BL6090, t_BL150180,
|
||||
p_SFC, topo, stopo, gh_c, t_c):
|
||||
p = self.newGrid(-1)
|
||||
tmb = self.newGrid(-1)
|
||||
tms = self.newGrid(-1)
|
||||
# go up the column to figure out the surface pressure
|
||||
for i in xrange(1, gh_c.shape[0]):
|
||||
higher = greater(gh_c[i], topo)
|
||||
# interpolate the pressure at topo height
|
||||
val = self.linear(gh_c[i], gh_c[i - 1],
|
||||
log(self.pres[i]), log(self.pres[i - 1]), topo)
|
||||
val.clip(-.00001, 10, val)
|
||||
|
||||
m = logical_and(equal(p, -1), higher)
|
||||
p[m] = exp(val)[m]
|
||||
# interpolate the temperature at true elevation
|
||||
tval1 = self.linear(gh_c[i], gh_c[i - 1], t_c[i], t_c[i - 1], topo)
|
||||
|
||||
m = logical_and(equal(tmb, -1), higher)
|
||||
tmb[m] = tval1[m]
|
||||
# interpolate the temperature at model elevation
|
||||
tval2 = self.linear(gh_c[i], gh_c[i - 1], t_c[i], t_c[i - 1], stopo)
|
||||
|
||||
m = logical_and(equal(tms, -1), greater(gh_c[i], stopo))
|
||||
tms[m] = tval2[m]
|
||||
|
||||
p_SFC /= 100
|
||||
# define the pres. of each of the boundary layers
|
||||
pres = [p_SFC, p_SFC - 15, p_SFC - 75, p_SFC - 168]
|
||||
|
||||
# list of temperature grids
|
||||
temps = [t_FHAG2, t_BL030, t_BL6090, t_BL150180]
|
||||
st = self.newGrid(-1)
|
||||
# Calculate the lapse rate in units of pressure
|
||||
for i in xrange(1, len(pres)):
|
||||
val = self.linear(pres[i], pres[i - 1], temps[i], temps[i - 1], p)
|
||||
gm = greater(pres[i - 1], p)
|
||||
lm = less_equal(pres[i], p)
|
||||
mask = logical_and(gm, lm)
|
||||
|
||||
m = logical_and(equal(st, -1), mask)
|
||||
st[m] = val[m]
|
||||
|
||||
# where topo level is above highest level in BL fields...use tmb
|
||||
m = logical_and(equal(st,-1),less(p,p_SFC-135))
|
||||
st[m] = tmb[m]
|
||||
|
||||
# where topo level is below model surface...use difference
|
||||
# of t at pressure of surface and tFHAG2 and subtract from tmb
|
||||
m = equal(st, -1)
|
||||
st[m] = (tmb - tms + t_FHAG2)[m]
|
||||
return self.KtoF(st)
|
||||
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates dew point from the specified pressure, temp and rh
|
||||
## fields.
|
||||
##-------------------------------------------------------------------------
|
||||
def calcTd(self, p_SFC, T, t_FHAG2, stopo, topo, rh_FHAG2):
|
||||
# at the model surface
|
||||
sfce = rh_FHAG2 / 100 * self.esat(t_FHAG2)
|
||||
w = (0.622 * sfce) / ((p_SFC + 0.0001) / 100 - sfce)
|
||||
# at the true surface
|
||||
tsfce = self.esat(self.FtoK(T))
|
||||
dpdz = 287.04 * t_FHAG2 / (p_SFC / 100 * 9.8) # meters / millibar
|
||||
newp = p_SFC / 100 + (stopo - topo) / dpdz
|
||||
ws = (0.622 * tsfce) / (newp - tsfce)
|
||||
rh = w / ws
|
||||
# Finally, calculate the dew point
|
||||
tsfcesat = rh * tsfce
|
||||
tsfcesat.clip(0.00001, tsfcesat, tsfcesat)
|
||||
b = 26.66082 - log(tsfcesat)
|
||||
td = (b - sqrt(b * b - 223.1986)) / 0.0182758048
|
||||
td = self.KtoF(td)
|
||||
|
||||
m = w > ws
|
||||
td[m] = T[m]
|
||||
return td
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates RH from the T and Td grids
|
||||
##-------------------------------------------------------------------------
|
||||
def calcRH(self, T, Td):
|
||||
Tc = .556 * (T - 32.0)
|
||||
Tdc = .556 * (Td - 32.0)
|
||||
Vt = 6.11 * pow(10, (Tc * 7.5 / (Tc + 237.3)))
|
||||
Vd = 6.11 * pow(10, (Tdc * 7.5 / (Tdc + 237.3)))
|
||||
RH = (Vd / Vt) * 100.0
|
||||
# Return the new value
|
||||
return RH
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Returns the maximum of the specified MaxRH and the RH grids
|
||||
##--------------------------------------------------------------------------
|
||||
def calcMaxRH(self, RH, MaxRH):
|
||||
if MaxRH is None:
|
||||
return RH
|
||||
return maximum(MaxRH, RH)
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Returns the minimum of the specified MinRH and RH grids
|
||||
##--------------------------------------------------------------------------
|
||||
def calcMinRH(self, RH, MinRH):
|
||||
if MinRH is None:
|
||||
return RH
|
||||
return minimum(MinRH, RH)
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates QPF from the total precip field out of the model
|
||||
##-------------------------------------------------------------------------
|
||||
def calcQPF(self, cp_SFC, lgsp_SFC):
|
||||
tp_SFC = cp_SFC + lgsp_SFC
|
||||
qpf = tp_SFC / 25.4 # convert from millimeters to inches
|
||||
return qpf
|
||||
|
||||
def calcSky(self, rh_c, gh_c, topo, p_SFC):
|
||||
return self.skyFromRH(rh_c, gh_c, topo, p_SFC)
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates Prob. of Precip. based on QPF and RH cube. Where there
|
||||
## is QPF > 0 ramp the PoP from (0.01, 35%) to 100%. Then in areas
|
||||
## of QPF < 0.2 raise the PoP if it's very humid.
|
||||
##-------------------------------------------------------------------------
|
||||
def calcPoP(self, gh_c, rh_c, QPF, topo):
|
||||
rhavg = where(less(gh_c, topo), float32(-1), rh_c)
|
||||
rhavg[greater(gh_c, topo + 5000 * 0.3048)] = -1
|
||||
count = not_equal(rhavg, -1)
|
||||
rhavg[equal(rhavg, -1)] = 0
|
||||
count = add.reduce(count, 0, dtype=float32)
|
||||
rhavg = add.reduce(rhavg, 0)
|
||||
## add this much based on humidity only
|
||||
dpop = where(count, rhavg / (count + .001), 0) - 70.0
|
||||
dpop[less(dpop, -30)] = -30
|
||||
## calculate the base PoP
|
||||
pop = where(less(QPF, 0.02), QPF * 1000, QPF * 350 + 13)
|
||||
pop += dpop # add the adjustment based on humidity
|
||||
pop.clip(0, 100, pop) # clip to 100%
|
||||
return pop
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates the Freezing level based on height and temperature
|
||||
## cubes. Finds the height at which freezing occurs.
|
||||
##-------------------------------------------------------------------------
|
||||
def calcFzLevel(self, gh_FRZ):
|
||||
return gh_FRZ / 0.3048
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates the Snow level based on wet-bulb zero height.
|
||||
##-------------------------------------------------------------------------
|
||||
def calcSnowLevel(self, gh_c, t_c, rh_c):
|
||||
# Only use the levels that are >= freezind (plus one level)
|
||||
# This is a performance and memory optimization
|
||||
clipindex = 2
|
||||
for i in xrange(t_c.shape[0] - 1, -1, -1):
|
||||
if maximum.reduce(maximum.reduce(t_c[i])) >= 273.15:
|
||||
clipindex = i + 1
|
||||
break
|
||||
gh_c = gh_c[:clipindex, :, :]
|
||||
t_c = t_c[:clipindex, :, :]
|
||||
rh_c = rh_c[:clipindex, :, :]
|
||||
|
||||
snow = self.newGrid(-1)
|
||||
#
|
||||
# make pressure cube
|
||||
#
|
||||
pmb = ones_like(gh_c)
|
||||
for i in xrange(gh_c.shape[0]):
|
||||
pmb[i] = self.pres[i]
|
||||
pmb.clip(1, 1050, pmb)
|
||||
#
|
||||
# convert temps to C and limit to reasonable values
|
||||
#
|
||||
tc = t_c - 273.15
|
||||
tc.clip(-120, 60, tc)
|
||||
#
|
||||
# limit RH to reasonable values
|
||||
#
|
||||
rh = clip(rh_c, 0.5, 99.5)
|
||||
#
|
||||
# calculate the wetbulb temperatures
|
||||
# (this is expensive - even in numeric python - and somewhat
|
||||
# wasteful, since you do not need to calculate the wetbulb
|
||||
# temp for all levels when it may cross zero way down toward
|
||||
# the bottom. Nevertheless - all the gridpoints will cross
|
||||
# zero at different levels - so you cannot know ahead of time
|
||||
# how high up to calculate them. In the end - this was the
|
||||
# most expedient way to code it - and it works - so I stuck
|
||||
# with it.
|
||||
#
|
||||
wetb = self.Wetbulb(tc, rh, pmb)
|
||||
tc = rh = pmb = None
|
||||
#
|
||||
# find the zero level
|
||||
#
|
||||
for i in xrange(1, gh_c.shape[0]):
|
||||
try:
|
||||
val = gh_c[i - 1] + (gh_c[i] - gh_c[i - 1]) / (wetb[i] - wetb[i - 1])\
|
||||
* (-wetb[i - 1])
|
||||
except:
|
||||
val = gh_c[i]
|
||||
m = logical_and(equal(snow, -1), less_equal(wetb[i], 0))
|
||||
snow[m] = val[m]
|
||||
#
|
||||
# convert to feet
|
||||
#
|
||||
snow /= 0.3048
|
||||
|
||||
return snow
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates Snow amount based on the Temp, Freezing level, QPF,
|
||||
## topo and Weather grid
|
||||
##-------------------------------------------------------------------------
|
||||
def calcSnowAmt(self, T, FzLevel, QPF, topo, Wx):
|
||||
# figure out the snow to liquid ratio
|
||||
snowr = T * -0.5 + 22.5
|
||||
snowr[less(T, 9)] = 20
|
||||
snowr[greater_equal(T, 30)] = 0
|
||||
# calc. snow amount based on the QPF and the ratio
|
||||
snowamt = where(less_equal(FzLevel - 1000, topo / 0.3048),
|
||||
snowr * QPF, float32(0))
|
||||
# Only make snow at points where the weather is snow
|
||||
snowmask = logical_or(equal(Wx[0], 1), equal(Wx[0], 3))
|
||||
snowmask = logical_or(snowmask, logical_or(equal(Wx[0], 7),
|
||||
equal(Wx[0], 9)))
|
||||
snowamt[logical_not(snowmask)] = 0
|
||||
return snowamt
|
||||
|
||||
##--------------------------------------------------------------------------
|
||||
## Calculate the Haines index based on the temp and RH cubes
|
||||
## Define self.whichHainesIndex to be "HIGH", "MEDIUM", or "LOW".
|
||||
## Default is "HIGH".
|
||||
##--------------------------------------------------------------------------
|
||||
def calcHaines(self, t_c, rh_c):
|
||||
return self.hainesIndex(self.whichHainesIndex, t_c, rh_c)
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates the mixing height for the given sfc temperature,
|
||||
## temperature cube, height cube and topo
|
||||
##-------------------------------------------------------------------------
|
||||
def calcMixHgt(self, T, topo, t_c, gh_c):
|
||||
mask = greater_equal(gh_c, topo)
|
||||
pt = []
|
||||
for i in xrange(len(self.pres)): # for each pres. level
|
||||
p = self.newGrid(self.pres[i]) # get the pres. value in mb
|
||||
tmp = self.ptemp(t_c[i], p) # calculate the pot. temp
|
||||
pt = pt + [tmp] # add to the list
|
||||
pt = array(pt)
|
||||
pt[logical_not(mask)] = 0
|
||||
avg = add.accumulate(pt, 0)
|
||||
count = add.accumulate(mask, 0)
|
||||
mh = self.newGrid(-1)
|
||||
# for each pres. level, calculate a running avg. of pot temp.
|
||||
# As soon as the next point deviates from the running avg by
|
||||
# more than 3 deg. C, interpolate to get the mixing height.
|
||||
for i in xrange(1, avg.shape[0]):
|
||||
runavg = avg[i] / (count[i] + .0001)
|
||||
diffpt = pt[i] - runavg
|
||||
# calc. the interpolated mixing height
|
||||
tmh = self.linear(pt[i], pt[i - 1], gh_c[i], gh_c[i - 1], runavg)
|
||||
# assign new values if the difference is greater than 3
|
||||
m = logical_and(logical_and(mask[i], equal(mh, -1)), greater(diffpt, 3))
|
||||
mh[m] = tmh[m]
|
||||
mh -= topo
|
||||
mh /= 0.3048 # convert to feet
|
||||
return mh
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Converts the lowest available wind level from m/s to knots
|
||||
##-------------------------------------------------------------------------
|
||||
def calcWind(self, wind_FHAG10):
|
||||
mag = wind_FHAG10[0] # get the wind grids
|
||||
dir = wind_FHAG10[1]
|
||||
mag += 1.94 # convert m/s to knots
|
||||
dir.clip(0, 359.5, dir)
|
||||
return (mag, dir)
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates the wind at 3000 feet AGL.
|
||||
##-------------------------------------------------------------------------
|
||||
def calcFreeWind(self, gh_c, wind_c, topo):
|
||||
wm = wind_c[0]
|
||||
wd = wind_c[1]
|
||||
# Make a grid that's topo + 3000 feet (914 meters)
|
||||
fatopo = topo + 914.4
|
||||
# find the points that are above the 3000 foot level
|
||||
mask = greater_equal(gh_c, fatopo)
|
||||
# initialize the grids into which the value are stored
|
||||
famag = self.newGrid(-1)
|
||||
fadir = self.newGrid(-1)
|
||||
# start at the bottom and store the first point we find that's
|
||||
# above the topo + 3000 feet level.
|
||||
for i in xrange(wind_c[0].shape[0]):
|
||||
m = logical_and(equal(famag, -1), mask[i])
|
||||
famag[m] = wm[i][m]
|
||||
|
||||
m = logical_and(equal(fadir, -1), mask[i])
|
||||
fadir[m] = wd[i][m]
|
||||
|
||||
fadir.clip(0, 359.5, fadir) # clip the value to 0, 360
|
||||
famag *= 1.94 # convert to knots
|
||||
return (famag, fadir) # return the tuple of grids
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates the average wind vector in the mixed layer as defined
|
||||
## by the mixing height. This function creates a mask that identifies
|
||||
## all grid points between the ground and the mixing height and calculates
|
||||
## a vector average of the wind field in that layer.
|
||||
##-------------------------------------------------------------------------
|
||||
def calcTransWind(self, MixHgt, wind_c, gh_c, topo):
|
||||
nmh = MixHgt * 0.3048 # convert MixHt from feet -> meters
|
||||
u, v = self._getUV(wind_c[0], wind_c[1]) # get the wind grids
|
||||
# set a mask at points between the topo and topo + MixHt
|
||||
mask = logical_and(greater_equal(gh_c, topo),
|
||||
less_equal(gh_c, nmh + topo))
|
||||
# set the points outside the layer to zero
|
||||
u[logical_not(mask)] = 0
|
||||
v[logical_not(mask)] = 0
|
||||
mask = add.reduce(mask).astype(float32)
|
||||
mmask = mask + 0.0001
|
||||
# calculate the average value in the mixed layerlayer
|
||||
u = where(mask, add.reduce(u) / mmask, float32(0))
|
||||
v = where(mask, add.reduce(v) / mmask, float32(0))
|
||||
# convert u, v to mag, dir
|
||||
tmag, tdir = self._getMD(u, v)
|
||||
tdir.clip(0, 359.5, tdir)
|
||||
tmag *= 1.94 # convert to knots
|
||||
tmag.clip(0, 125, tmag) # clip speed to 125 knots
|
||||
return (tmag, tdir)
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Uses a derivation of the Bourgouin allgorithm to calculate precipitation
|
||||
## type, and other algorithms to determine the coverage and intensity.
|
||||
## The Bourgoin technique figures out precip type from calculating how
|
||||
## long a hydrometer is exposed to alternating layers of above zero (C) and
|
||||
## below zero temperature layers. This tool calculates at each grid point
|
||||
## which of the four Bourgouin cases apply. Then the appropriate algorithm
|
||||
## is applied to that case that further refines the precip. type. Once the
|
||||
## type is determined, other algorithms are used to determine the coverage
|
||||
## and intensity. See the Weather and Forecasting Journal article Oct. 2000,
|
||||
## "A Method to Determine Precipitation Types", by Pierre Bourgouin
|
||||
##-------------------------------------------------------------------------
|
||||
def calcWx(self, QPF, T, p_SFC, t_c, gh_c, topo, lgsp_SFC, cp_SFC):
|
||||
tp_SFC = cp_SFC + lgsp_SFC
|
||||
gh_c = gh_c[:13, :, :]
|
||||
t_c = t_c[:13, :, :]
|
||||
T = self.FtoK(T)
|
||||
p_SFC = p_SFC / 100 # sfc pres. in mb
|
||||
pres = self.pres
|
||||
a1 = self.empty()
|
||||
a2 = self.empty()
|
||||
a3 = self.empty()
|
||||
aindex = self.empty()
|
||||
# Go through the levels to identify each case type 0-3
|
||||
for i in xrange(1, gh_c.shape[0] - 1):
|
||||
# get the sfc pres. and temp.
|
||||
pbot = where(greater(gh_c[i - 1], topo), pres[i - 1], p_SFC)
|
||||
tbot = where(greater(gh_c[i - 1], topo), t_c[i - 1], T)
|
||||
# Calculate the area of this layer in Temp/pres coordinates
|
||||
a11, a22, cross = self.getAreas(pbot, tbot, pres[i], t_c[i])
|
||||
topomask = greater(gh_c[i], topo)
|
||||
|
||||
m = logical_and(equal(aindex, 0), topomask)
|
||||
a1[m] += a11[m]
|
||||
|
||||
m = logical_and(equal(aindex, 1), topomask)
|
||||
a2[m] += a11[m]
|
||||
|
||||
m = logical_and(equal(aindex, 2), topomask)
|
||||
a3[m] += a11[m]
|
||||
|
||||
topomask = logical_and(topomask, cross)
|
||||
aindex = where(topomask, aindex + 1, aindex)
|
||||
|
||||
m = logical_and(equal(aindex, 0), topomask)
|
||||
a1[m] += a22[m]
|
||||
|
||||
m = logical_and(equal(aindex, 1), topomask)
|
||||
a2[m] += a22[m]
|
||||
|
||||
m = logical_and(equal(aindex, 2), topomask)
|
||||
a3[m] += a22[m]
|
||||
|
||||
# Now apply a different algorithm for each type
|
||||
key = ['<NoCov>:<NoWx>:<NoInten>:<NoVis>:',
|
||||
"Wide:S:-:<NoVis>:", "Wide:R:-:<NoVis>:",
|
||||
"Wide:S:-:<NoVis>:^Wide:R:-:<NoVis>:",
|
||||
'Wide:ZR:-:<NoVis>:', 'Wide:IP:-:<NoVis>:',
|
||||
'Wide:ZR:-:<NoVis>:^Wide:IP:-:<NoVis>:',
|
||||
"Sct:SW:-:<NoVis>:", "Sct:RW:-:<NoVis>:",
|
||||
"Sct:SW:-:<NoVis>:^Sct:RW:-:<NoVis>:",
|
||||
"Chc:ZR:-:<NoVis>:", 'Chc:IP:-:<NoVis>:',
|
||||
'Chc:ZR:-:<NoVis>:^Chc:IP:-:<NoVis>:']
|
||||
|
||||
wx = self.empty(int8)
|
||||
# Case d (snow)
|
||||
snowmask = equal(aindex, 0)
|
||||
wx[logical_and(snowmask, greater(a1, 0))] = 2
|
||||
wx[logical_and(snowmask, less_equal(a1, 0))] = 1
|
||||
|
||||
# Case c (rain / snow / rainSnowMix)
|
||||
srmask = equal(aindex, 1)
|
||||
wx[logical_and(srmask, less(a1, 5.6))] = 1
|
||||
wx[logical_and(srmask, greater(a1, 13.2))] = 2
|
||||
wx[logical_and(srmask,
|
||||
logical_and(greater_equal(a1, 5.6),
|
||||
less(a1, 13.2)))] = 3
|
||||
|
||||
# Case a (Freezing Rain / Ice Pellets)
|
||||
ipmask = equal(aindex, 2)
|
||||
ipm = greater(a1, a2 * 0.66 + 66)
|
||||
wx[logical_and(ipmask, ipm)] = 5
|
||||
zrm = less(a1, a2 * 0.66 + 46)
|
||||
wx[logical_and(ipmask, zrm)] = 4
|
||||
zrm = logical_not(zrm)
|
||||
ipm = logical_not(ipm)
|
||||
wx[logical_and(ipmask, logical_and(zrm, ipm))] = 6
|
||||
|
||||
# Case b (Ice pellets / rain)
|
||||
cmask = greater_equal(aindex, 3)
|
||||
ipmask = logical_and(less(a3, 2), cmask)
|
||||
wx[logical_and(ipmask, less(a1, 5.6))] = 1
|
||||
wx[logical_and(ipmask, greater(a1, 13.2))] = 2
|
||||
wx[logical_and(ipmask, logical_and(greater_equal(a1, 5.6),
|
||||
less_equal(a1, 13.2)))] = 3
|
||||
|
||||
ipmask = logical_and(greater_equal(a3, 2), cmask)
|
||||
wx[logical_and(ipmask, greater(a1, 66 + 0.66 * a2))] = 5
|
||||
wx[logical_and(ipmask, less(a1, 46 + 0.66 * a2))] = 4
|
||||
wx[logical_and(ipmask, logical_and(greater_equal(a1, 46 + 0.66 * a2),
|
||||
less_equal(a1, 66 + 0.66 * a2)))] = 6
|
||||
|
||||
# Make showers (scattered/Chc)
|
||||
convecMask = greater(cp_SFC / (tp_SFC + .001), 0.5)
|
||||
wx[logical_and(not_equal(wx, 0), convecMask)] += 6
|
||||
|
||||
# This section commented out since bli is no longer available for RUC.
|
||||
# Thunder
|
||||
#for i in xrange(len(key)):
|
||||
#tcov = string.split(key[i], ":")[0]
|
||||
#if tcov == "Chc" or tcov == "<NoCov>":
|
||||
#tcov = "Sct"
|
||||
#key.append(key[i] + "^" + tcov
|
||||
#+ ":T:<NoInten>:<NoVis>:")
|
||||
#wx = where(less_equal(bli_SFC, -3), wx + 13, wx)
|
||||
|
||||
# No wx where no qpf
|
||||
wx[less(QPF, 0.01)] = 0
|
||||
return(wx, key)
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates chance of wetting rain based on QPF.
|
||||
##-------------------------------------------------------------------------
|
||||
def calcCWR(self, QPF):
|
||||
m1 = less(QPF, 0.01) # all the places that are dry
|
||||
m2 = greater_equal(QPF, 0.3) # all the places that are wet
|
||||
# all the places that are 0.01 to 0.10
|
||||
m3 = logical_and(greater_equal(QPF, 0.01), less_equal(QPF, 0.1))
|
||||
# all the places that are 0.1 to 0.3
|
||||
m4 = logical_and(greater(QPF, 0.1), less(QPF, 0.3))
|
||||
# assign 0 to the dry grid point, 100 to the wet grid points,
|
||||
# and a ramping function to all point in between
|
||||
cwr = where(m1, float32(0), where(m2, float32(100),
|
||||
where(m3, 444.4 * (QPF - 0.01) + 10,
|
||||
where(m4, 250 * (QPF - 0.1) + 50,
|
||||
QPF))))
|
||||
return cwr
|
||||
|
||||
##-------------------------------------------------------------------------
|
||||
## Calculates Lightning Activity Level based on total precip., lifted index
|
||||
## and 3-D relative humidity.
|
||||
##-------------------------------------------------------------------------
|
||||
def calcLAL(self, bli_SFC, lgsp_SFC, cp_SFC, rh_c, rh_FHAG2):
|
||||
tp_SFC = cp_SFC + lgsp_SFC
|
||||
lal = self.newGrid(1)
|
||||
# Add one to lal if we have 0.5 mm of precip.
|
||||
lal[logical_and(greater(cp_SFC, 0), greater(tp_SFC / cp_SFC, 0.5))] += 1
|
||||
|
||||
# make an average rh field
|
||||
midrh = add.reduce(rh_c[6:9], 0) / 3
|
||||
# Add one to lal if mid-level rh high and low level rh low
|
||||
lal[logical_and(greater(midrh, 70), less(rh_FHAG2, 30))] += 1
|
||||
|
||||
# Add on to lal if lifted index is <-3 and another if <-5
|
||||
lal[less(bli_SFC, -3)] += 1
|
||||
lal[less(bli_SFC, -5)] += 1
|
||||
return lal
|
||||
|
||||
def main():
|
||||
RUC13Forecaster().run()
|
|
@ -1,4 +1,4 @@
|
|||
# Version 2018.02.26-2
|
||||
# Version 2018.06.05
|
||||
|
||||
import GenericHazards
|
||||
import string, time, os, re, types, copy, LogStream, collections
|
||||
|
@ -1253,7 +1253,7 @@ class TextProduct(HLSTCV_Common.TextProduct):
|
|||
self.debug_print("Looking at zone %s" % (zone), 1)
|
||||
for key in advisory["ZoneData"][zone]:
|
||||
if "Threat" not in key or "highestHunkerDown" in key:
|
||||
break
|
||||
continue
|
||||
|
||||
if key not in seenValidThreatLevel:
|
||||
seenValidThreatLevel[key] = False
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
# This is a base file that is not intended to be overridden.
|
||||
##
|
||||
|
||||
# Version 2017.12.13-0
|
||||
# Version 2018.6.5-0
|
||||
|
||||
import GenericHazards
|
||||
import JsonSupport
|
||||
|
@ -1457,7 +1457,7 @@ class SectionCommon():
|
|||
self._sectionHeaderName = sectionHeaderName
|
||||
self._segment = segment
|
||||
self._tr = None
|
||||
self.isThreatNoneForEntireStorm = True
|
||||
self.isThreatNoneForEntireStorm = False
|
||||
|
||||
def _isThreatNoneForEntireStorm(self, threatName):
|
||||
previousAdvisories = self._textProduct._getPreviousAdvisories()
|
||||
|
@ -1471,7 +1471,7 @@ class SectionCommon():
|
|||
if advisory["ZoneData"][self._segment][threatName] != "None":
|
||||
return False
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
def _setProductPartValue(self, dictionary, productPartName, value):
|
||||
dictionary[self._sectionName + '._' + productPartName] = value
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
-->
|
||||
<aliasList caseSensitive="true" namespace="gfeParamInfo">
|
||||
<alias base="MOSGuide-HI">mosGuideNDFD</alias>
|
||||
<alias base="GFS217">gfs20km</alias>
|
||||
<alias base="GFS215">gfs20km</alias>
|
||||
<alias base="AK-GFS22">gfs20km</alias>
|
||||
<alias base="GFS20">gfs20km</alias>
|
||||
<alias base="GFS20-PAC">gfs20km</alias>
|
||||
<alias base="GFS20-PRICO">gfs20km</alias>
|
||||
<alias base="PR-GFS">gfs20km</alias>
|
||||
<alias base="estofsAK">ESTOFS</alias>
|
||||
<alias base="estofsEP">ESTOFS</alias>
|
||||
<alias base="estofsHI">ESTOFS</alias>
|
||||
|
@ -73,16 +73,16 @@
|
|||
<alias base="MRF26">mrf202</alias>
|
||||
<alias base="GFS201">gfs201</alias>
|
||||
<alias base="mrfNH">mrf201</alias>
|
||||
<alias base="GFS213">gfs213</alias>
|
||||
<alias base="GFS95">gfs95</alias>
|
||||
<alias base="AVN211">avn211</alias>
|
||||
<alias base="mesoEta212">mesoEta212</alias>
|
||||
<alias base="mesoEta215">mesoEta215</alias>
|
||||
<alias base="ETA212">eta212</alias>
|
||||
<alias base="NAM40">NAM40</alias>
|
||||
<alias base="NAM20">NAM20</alias>
|
||||
<alias base="NAM40">eta212</alias>
|
||||
<alias base="AVN203">avn203</alias>
|
||||
<alias base="MRF203">mrf203</alias>
|
||||
<alias base="MRF204">mrf204</alias>
|
||||
<alias base="MRF205">mrf205</alias>
|
||||
<alias base="ETA207">eta207</alias>
|
||||
<alias base="AK-NAM95">eta207</alias>
|
||||
<alias base="AVN-NorthernHemisphere">avnNH</alias>
|
||||
<alias base="AVN37">avnNH</alias>
|
||||
<alias base="AVN38">avnNH</alias>
|
||||
|
@ -92,7 +92,7 @@
|
|||
<alias base="AVN42">avnNH</alias>
|
||||
<alias base="AVN43">avnNH</alias>
|
||||
<alias base="AVN44">avnNH</alias>
|
||||
<alias base="GWW233">gww233</alias>
|
||||
<alias base="WaveWatch">gww233</alias>
|
||||
<alias base="GWW21">gww233</alias>
|
||||
<alias base="GWW22">gww233</alias>
|
||||
<alias base="GWW23">gww233</alias>
|
||||
|
@ -101,26 +101,28 @@
|
|||
<alias base="SeaIce220">seaIce219</alias>
|
||||
<alias base="SeaIce173">seaIce219</alias>
|
||||
<alias base="SeaIce235">seaIce219</alias>
|
||||
<alias base="RUC236">ruc236</alias>
|
||||
<alias base="RAP40">rap40</alias>
|
||||
<alias base="AVN225">avn225</alias>
|
||||
<alias base="AKWAVE239">akWave239</alias>
|
||||
<alias base="WNAWAVE238">wnaWave238</alias>
|
||||
<alias base="mesoEta216">mesoEta216</alias>
|
||||
<alias base="mesoEta217">mesoEta217</alias>
|
||||
<alias base="ETA218">eta218</alias>
|
||||
<alias base="ETA242">eta242</alias>
|
||||
<alias base="AK-NAM45">AK-NAM45</alias>
|
||||
<alias base="AK-NAM22">AK-NAM22</alias>
|
||||
<alias base="NAM12">NAM12</alias>
|
||||
<alias base="AK-NAM11">eta242</alias>
|
||||
<alias base="ENPWAVE253">enpWave253</alias>
|
||||
<alias base="HurWind226">TPCtcm226</alias>
|
||||
<alias base="HurWind175">TCPtcm175</alias>
|
||||
<alias base="HurWind250">TPCtpm250</alias>
|
||||
<alias base="NICICE">nic218</alias>
|
||||
<alias base="AK-NICICE">nic242</alias>
|
||||
<alias base="GFS212">gfs212</alias>
|
||||
<alias base="DGEX">dgex185</alias>
|
||||
<alias base="AK-DGEX">dgex186</alias>
|
||||
<alias base="GFS40">gfs212</alias>
|
||||
<alias base="GFS160">gfs160</alias>
|
||||
<alias base="GFS254">gfs254</alias>
|
||||
<alias base="GFS161">gfs161</alias>
|
||||
<alias base="GFS199">gfs161</alias>
|
||||
<alias base="RUC130">ruc130</alias>
|
||||
<alias base="RAP13">RAP13</alias>
|
||||
<alias base="RTMA25">rtmaNDFD</alias>
|
||||
<alias base="URMA25">urmaNDFD</alias>
|
||||
<alias base="namdng25">NamDNG</alias>
|
||||
|
@ -150,7 +152,7 @@
|
|||
<alias base="GRLKwave">GRLKwave</alias>
|
||||
<alias base="MSAS">msas</alias>
|
||||
<alias base="GFSSouthernHemisphere">gfs201</alias>
|
||||
<alias base="mesoEta237">eta218</alias>
|
||||
<alias base="PR-NAM">NAM12</alias>
|
||||
<alias base="ENSEMBLE">ensembleNH</alias>
|
||||
<alias base="ENSEMBLE37">ensembleNH</alias>
|
||||
<alias base="ENSEMBLE38">ensembleNH</alias>
|
||||
|
@ -330,6 +332,7 @@
|
|||
<alias base="NationalBlendPR">NationalBlend</alias>
|
||||
<alias base="NationalBlendHI">NationalBlend</alias>
|
||||
<alias base="NationalBlendAK">NationalBlend</alias>
|
||||
<alias base="NationalBlendOC">NationalBlend</alias>
|
||||
<alias base="PGBlended">PGBlended</alias>
|
||||
<alias base="PGBlended-Night">PGBlended</alias>
|
||||
<alias base="NCOM-USEAST">ncom</alias>
|
||||
|
|
|
@ -284,6 +284,9 @@
|
|||
<Level key="FHAG10">
|
||||
<DatabaseLevel levelName="FHAG" levelOneValue="10.0" unit="m"/>
|
||||
</Level>
|
||||
<Level key="FHAG30">
|
||||
<DatabaseLevel levelName="FHAG" levelOneValue="30.0" unit="m"/>
|
||||
</Level>
|
||||
<Level key="FHAG80">
|
||||
<DatabaseLevel levelName="FHAG" levelOneValue="80.0" unit="m"/>
|
||||
</Level>
|
||||
|
@ -293,6 +296,9 @@
|
|||
<Level key="FHAG4000">
|
||||
<DatabaseLevel levelName="FHAG" levelOneValue="4000.0" unit="m"/>
|
||||
</Level>
|
||||
<Level key="FHAG0610">
|
||||
<DatabaseLevel levelName="FHAG" levelOneValue="0.0" levelTwoValue="610.0" unit="m"/>
|
||||
</Level>
|
||||
<Level key="FHAG01000">
|
||||
<DatabaseLevel levelName="FHAG" levelOneValue="0.0" levelTwoValue="1000.0" unit="m"/>
|
||||
</Level>
|
||||
|
@ -302,6 +308,9 @@
|
|||
<Level key="FHAG06000">
|
||||
<DatabaseLevel levelName="FHAG" levelOneValue="0.0" levelTwoValue="6000.0" unit="m"/>
|
||||
</Level>
|
||||
<Level key="FHAG61040000">
|
||||
<DatabaseLevel levelName="FHAG" levelOneValue="610.0" levelTwoValue="40000.0" unit="m"/>
|
||||
</Level>
|
||||
<Level key="FRZ">
|
||||
<DatabaseLevel levelName="FRZ" levelOneValue="0.0"/>
|
||||
</Level>
|
||||
|
@ -671,4 +680,7 @@
|
|||
<Level key="NTAT">
|
||||
<DatabaseLevel levelName="NTAT" levelOneValue="0.0"/>
|
||||
</Level>
|
||||
<Level key="MWSL">
|
||||
<DatabaseLevel levelName="MWSL" levelOneValue="0.0"/>
|
||||
</Level>
|
||||
</LevelMappings>
|
||||
|
|
|
@ -291,6 +291,17 @@
|
|||
<fcst>943200</fcst>
|
||||
<fcst>946800</fcst>
|
||||
<fcst>950400</fcst>
|
||||
<fcst>957600</fcst>
|
||||
<fcst>961200</fcst>
|
||||
<fcst>964800</fcst>
|
||||
<fcst>968400</fcst>
|
||||
<fcst>972000</fcst>
|
||||
<fcst>975600</fcst>
|
||||
<fcst>979200</fcst>
|
||||
<fcst>982800</fcst>
|
||||
<fcst>986400</fcst>
|
||||
<fcst>990000</fcst>
|
||||
<fcst>993600</fcst>
|
||||
</valtimeMINUSreftime>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>mnt</short_name>
|
||||
|
@ -466,27 +477,12 @@
|
|||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>ppi1hr</short_name>
|
||||
<long_name>1HR PPI</long_name>
|
||||
<units>%</units>
|
||||
<udunits>percent</udunits>
|
||||
<uiname>1hrPcpProbIndex</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>0</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>ppi6hr</short_name>
|
||||
<long_name>6HR PPI</long_name>
|
||||
<units>%</units>
|
||||
<udunits>percent</udunits>
|
||||
<uiname>6hrPcpProbIndex</uiname>
|
||||
<units>1ndex</units>
|
||||
<udunits>index</udunits>
|
||||
<uiname>PPI6hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
|
@ -546,14 +542,15 @@
|
|||
<long_name>Wind Direction</long_name>
|
||||
<units>degreeTrue</units>
|
||||
<udunits>degree_True</udunits>
|
||||
<uiname>windDir</uiname>
|
||||
<uiname>WD</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>360.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>FHAG 10</levelsDesc>
|
||||
<levelsDesc>FHAG 10, FHAG 0-610</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG10</level>
|
||||
<level>FHAG0610</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
|
@ -628,14 +625,15 @@
|
|||
<long_name>Wind Speed</long_name>
|
||||
<units>m/s</units>
|
||||
<udunits>meter/sec</udunits>
|
||||
<uiname>windSpeed</uiname>
|
||||
<uiname>WS</uiname>
|
||||
<valid_range>-150.0</valid_range>
|
||||
<valid_range>150.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>FHAG 10</levelsDesc>
|
||||
<levelsDesc>FHAG 10, FHAG 0-610</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG10</level>
|
||||
<level>FHAG0610</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
|
@ -708,26 +706,11 @@
|
|||
<valid_range>330.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>2 FHAG</levelsDesc>
|
||||
<levelsDesc>FHAG 2</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG2</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>totsn</short_name>
|
||||
<long_name>Total Snowfall</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meters</udunits>
|
||||
<uiname>SnowAmt</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>1000.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>0</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>snowlvl</short_name>
|
||||
<long_name>Snow Level</long_name>
|
||||
|
@ -753,7 +736,7 @@
|
|||
<valid_range>330.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>0</n3D>
|
||||
<levelsDesc>2 FHAG</levelsDesc>
|
||||
<levelsDesc>FHAG 2</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG2</level>
|
||||
</levels>
|
||||
|
@ -768,13 +751,13 @@
|
|||
<valid_range>330.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>0</n3D>
|
||||
<levelsDesc>2 FHAG</levelsDesc>
|
||||
<levelsDesc>FHAG 2</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG2</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>MaxTW</short_name>
|
||||
<short_name>maxtw</short_name>
|
||||
<long_name>Max Wetbulb Aloft</long_name>
|
||||
<units>K</units>
|
||||
<udunits>degree_Kelvin</udunits>
|
||||
|
@ -783,16 +766,16 @@
|
|||
<valid_range>330.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>0</n3D>
|
||||
<levelsDesc>EA</levelsDesc>
|
||||
<levelsDesc>FHAG 610-40000</levelsDesc>
|
||||
<levels>
|
||||
<level>EA</level>
|
||||
<level>FHAG61040000</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>ptyp</short_name>
|
||||
<long_name>Precipitation type</long_name>
|
||||
<units/>
|
||||
<udunits/>
|
||||
<units>1</units>
|
||||
<udunits>1</udunits>
|
||||
<uiname>pTyp</uiname>
|
||||
<valid_range>1.0</valid_range>
|
||||
<valid_range>5.0</valid_range>
|
||||
|
@ -903,9 +886,9 @@
|
|||
<valid_range>6000.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>EA</levelsDesc>
|
||||
<levelsDesc>FHAG 610-40000</levelsDesc>
|
||||
<levels>
|
||||
<level>EA</level>
|
||||
<level>FHAG61040000</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
|
@ -918,9 +901,9 @@
|
|||
<valid_range>6000.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>EA</levelsDesc>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>EA</level>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
|
@ -938,4 +921,440 @@
|
|||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>mixht</short_name>
|
||||
<long_name>Mixing Height</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meters</udunits>
|
||||
<uiname>MIXHT</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>3689.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>0</n3D>
|
||||
<levelsDesc>EA</levelsDesc>
|
||||
<levels>
|
||||
<level>EA</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>trwdir</short_name>
|
||||
<long_name>Transport Wind direction</long_name>
|
||||
<units>deg</units>
|
||||
<udunits>degrees</udunits>
|
||||
<uiname>TRWDIR</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>360.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>EA</levelsDesc>
|
||||
<levels>
|
||||
<level>EA</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>trwspd</short_name>
|
||||
<long_name>Transport Wind Speed</long_name>
|
||||
<units>m/s</units>
|
||||
<udunits>meter/sec</udunits>
|
||||
<uiname>TRWSPD</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>65.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>EA</levelsDesc>
|
||||
<levels>
|
||||
<level>EA</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>vrate</short_name>
|
||||
<long_name>Ventilation Rate</long_name>
|
||||
<units>m^2/s</units>
|
||||
<udunits>meter2/sec</udunits>
|
||||
<uiname>VRATE</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>49958.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>EA</levelsDesc>
|
||||
<levels>
|
||||
<level>EA</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>hindex6hr</short_name>
|
||||
<long_name>Haines Index</long_name>
|
||||
<units>index</units>
|
||||
<udunits>index</udunits>>
|
||||
<uiname>HINDEX6hr</uiname>
|
||||
<valid_range>2.0</valid_range>
|
||||
<valid_range>6.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>EA</levelsDesc>
|
||||
<levels>
|
||||
<level>EA</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>fosindx6hr</short_name>
|
||||
<long_name>Fosberg Fire Weather Index</long_name>
|
||||
<units>index</units>
|
||||
<udunits>index</udunits>>
|
||||
<uiname>FOSINDX6hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>llwshgt</short_name>
|
||||
<long_name>LLWS Height</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meter</udunits>
|
||||
<uiname>LLWSHgt</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>609.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>FHAG 0-610</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG0610</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>maxref1hr</short_name>
|
||||
<long_name>Simulated Maximum Reflectivity</long_name>
|
||||
<units>dBZ</units>
|
||||
<udunits>dBZ</udunits>
|
||||
<uiname>MAXREF1hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>FHAG 1000</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG1000</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>viliq</short_name>
|
||||
<long_name>Vertically Integrated Liquid</long_name>
|
||||
<units>kg/m^2</units>
|
||||
<udunits>kilogram/meters2</udunits>
|
||||
<uiname>VILIQ</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>EA</levelsDesc>
|
||||
<levels>
|
||||
<level>EA</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>retop</short_name>
|
||||
<long_name>Echo Tops</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meter</udunits>
|
||||
<uiname>RETOP</uiname>
|
||||
<valid_range>1.0</valid_range>
|
||||
<valid_range>88888.203</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>CTL</levelsDesc>
|
||||
<levels>
|
||||
<level>CTL</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>wgs50pct</short_name>
|
||||
<long_name>10-m Wind Gust</long_name>
|
||||
<units>knots</units>
|
||||
<udunits>knots</udunits>
|
||||
<uiname>WGS50pct</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>FHAG 10</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG10</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>ws50pct</short_name>
|
||||
<long_name>30-m/80-m Wind Speed</long_name>
|
||||
<units>m/s</units>
|
||||
<udunits>meter/sec</udunits>
|
||||
<uiname>WS50pct</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>FHAG 30, 80</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG30</level>
|
||||
<level>FHAG80</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>vis50pct</short_name>
|
||||
<long_name>Visibility</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meter</udunits>
|
||||
<uiname>Vis50pct</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100000.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>t50pct</short_name>
|
||||
<long_name>Air Temperature</long_name>
|
||||
<units>K</units>
|
||||
<udunits>degree_Kelvin</udunits>
|
||||
<uiname>T50pct</uiname>
|
||||
<valid_range>180.0</valid_range>
|
||||
<valid_range>330.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>FHAG 2</levelsDesc>
|
||||
<levels>
|
||||
<level>FHAG2</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>pmsl10pct</short_name>
|
||||
<long_name>10th percentile Mean Sea Level Pressure</long_name>
|
||||
<units>Pa</units>
|
||||
<udunits>pascal</udunits>
|
||||
<uiname>PMSL10pct</uiname>
|
||||
<valid_range>80000.0</valid_range>
|
||||
<valid_range>110000.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>MSL</levelsDesc>
|
||||
<levels>
|
||||
<level>MSL</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>pmsl50pct</short_name>
|
||||
<long_name>50th percentile Mean Sea Level Pressure</long_name>
|
||||
<units>Pa</units>
|
||||
<udunits>pascal</udunits>
|
||||
<uiname>PMSL50pct</uiname>
|
||||
<valid_range>80000.0</valid_range>
|
||||
<valid_range>110000.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>MSL</levelsDesc>
|
||||
<levels>
|
||||
<level>MSL</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>pmsl90pct</short_name>
|
||||
<long_name>90th percentile Mean Sea Level Pressure</long_name>
|
||||
<units>Pa</units>
|
||||
<udunits>pascal</udunits>
|
||||
<uiname>PMSL90pct</uiname>
|
||||
<valid_range>80000.0</valid_range>
|
||||
<valid_range>110000.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>MSL</levelsDesc>
|
||||
<levels>
|
||||
<level>MSL</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>htsgw</short_name>
|
||||
<long_name>Significant Wave Height</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meter</udunits>
|
||||
<uiname>HTSGW</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>50.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>pwther</short_name>
|
||||
<long_name>Predominant Weather</long_name>
|
||||
<units>Numeric</units>
|
||||
<udunits>Numeric</udunits>
|
||||
<uiname>PWTHER</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>138.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>totsn1hr</short_name>
|
||||
<long_name>1-h Snow Accumulation</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meter</udunits>
|
||||
<uiname>TOTSN1hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>3.78</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>ficeac1hr</short_name>
|
||||
<long_name>1-h Ice Accumulation</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meter</udunits>
|
||||
<uiname>FICEAC1hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>15</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>totsn6hr</short_name>
|
||||
<long_name>6-h Snow Accumulation</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meter</udunits>
|
||||
<uiname>TOTSN6hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>1000.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>ficeac6hr</short_name>
|
||||
<long_name>6-h Ice Accumulation</long_name>
|
||||
<units>m</units>
|
||||
<udunits>meter</udunits>
|
||||
<uiname>FICEAC6hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>15.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>ppi1hr</short_name>
|
||||
<long_name>1-h Precipitation Potential Index</long_name>
|
||||
<units>%</units>
|
||||
<udunits>percent</udunits>
|
||||
<uiname>PPI1hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>thp1hr</short_name>
|
||||
<long_name>1-h SREF-based Prob. of a Thunderstorm</long_name>
|
||||
<units>%</units>
|
||||
<udunits>percent</udunits>
|
||||
<uiname>ThP1hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>drytpprob3hr</short_name>
|
||||
<long_name>3-h SREF-based Prob. of a Dry Thunderstorm</long_name>
|
||||
<units>%</units>
|
||||
<udunits>percent</udunits>
|
||||
<uiname>DRYTPPROB3hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>100.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>tp10pct6hr</short_name>
|
||||
<long_name>10th percentile 6hr Quant</long_name>
|
||||
<units>millimeter</units>
|
||||
<udunits>mm</udunits>
|
||||
<uiname>TP10pct6hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>1000.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>tp50pct6hr</short_name>
|
||||
<long_name>50th percentile 6hr Quant</long_name>
|
||||
<units>millimeter</units>
|
||||
<udunits>mm</udunits>
|
||||
<uiname>TP50pct6hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>1000.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xsi:type="parameterInfo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<short_name>tp90pct6hr</short_name>
|
||||
<long_name>90th percentile 6hr Quant</long_name>
|
||||
<units>millimeter</units>
|
||||
<udunits>mm</udunits>
|
||||
<uiname>TP90pct6hr</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>1000.0</valid_range>
|
||||
<fillValue>-999999.0</fillValue>
|
||||
<n3D>1</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
</gridParamInfo>
|
||||
|
|
|
@ -85,21 +85,6 @@
|
|||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>tpHPC</short_name>
|
||||
<long_name>6 hr Total Precip</long_name>
|
||||
<units>mm</units>
|
||||
<udunits>millimeter</udunits>
|
||||
<uiname>totPrecip</uiname>
|
||||
<valid_range>0.0</valid_range>
|
||||
<valid_range>1000.0</valid_range>
|
||||
<fillValue>-99999.0</fillValue>
|
||||
<n3D>0</n3D>
|
||||
<levelsDesc>SFC</levelsDesc>
|
||||
<levels>
|
||||
<level>SFC</level>
|
||||
</levels>
|
||||
</gridParameterInfo>
|
||||
<gridParameterInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="parameterInfo">
|
||||
<short_name>tpALR</short_name>
|
||||
<long_name>6 hr Total Precip for RFC-> ALR</long_name>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<!--
|
||||
Mar 20, 2013 #1774 randerso Added forecast hours out to 18
|
||||
Jun 19, 2013 #2044 randerso Updated to match model
|
||||
Feb 24 20153 DCS14537 byin Added HPBL for RUC13
|
||||
Feb 24 20153 DCS14537 byin Added HPBL for RAP13
|
||||
Jun 13, 2016 #17308 bhunderm Corrected LI units
|
||||
-->
|
||||
|
||||
|
|
31
edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml
Executable file → Normal file
31
edexOsgi/com.raytheon.edex.plugin.gfe/utility/common_static/base/parameter/alias/gfeParamName.xml
Executable file → Normal file
|
@ -28,7 +28,7 @@
|
|||
Mar 31, 2014 #2934 dgilling Updated params for pSurge2.0/PHISH data.
|
||||
Jul 03, 2014 DR 14068 mfoster Added parameters for 3km AK-RTMA
|
||||
Dec 15, 2014 DR 14024 jwatson Added parameters for 2.5km GFSLAMPGrid
|
||||
Feb 24, 2015 DR 16671 byin Added HPBL for RUC13
|
||||
Feb 24, 2015 DR 16671 byin Added HPBL for RAP13
|
||||
May 21, 2015 DR 17515 bhunder Added parameters for URMA25
|
||||
Jun 29, 2015 #4537 rferrel Added parameters for HRRR.
|
||||
Oct 08, 2015 #4958 dgilling Added parameters for NationalBlend.
|
||||
|
@ -593,9 +593,34 @@
|
|||
<alias base="PTypIcePellets">ptypicepellets</alias>
|
||||
<alias base="SNOWLVL">snowlvl</alias>
|
||||
<alias base="SNOWRATIO">snowratio</alias>
|
||||
<alias base="PBE">pbe</alias>
|
||||
<alias base="NBE">nbe</alias>
|
||||
<alias base="RIPCOP">ripcop</alias>
|
||||
<alias base="EROSNP">erosnp</alias>
|
||||
<alias base="OWASHP">owashp</alias>
|
||||
<alias base="MIXHT">mixht</alias>
|
||||
<alias base="TRWSPD">trwspd</alias>
|
||||
<alias base="TRWDIR">trwdir</alias>
|
||||
<alias base="VRATE">vrate</alias>
|
||||
<alias base="HINDEX6hr">hindex6hr</alias>
|
||||
<alias base="FOSINDX6hr">fosindx6hr</alias>
|
||||
<alias base="MAXREF1hr">maxref1hr</alias>
|
||||
<alias base="PWTHER">pwther</alias>
|
||||
<alias base="TOTSN1hr">totsn1hr</alias>
|
||||
<alias base="FICEAC1hr">ficeac1hr</alias>
|
||||
<alias base="TOTSN6hr">totsn6hr</alias>
|
||||
<alias base="FICEAC6hr">ficeac6hr</alias>
|
||||
<alias base="TP10pct6hr">tp10pct6hr</alias>
|
||||
<alias base="TP50pct6hr">tp50pct6hr</alias>
|
||||
<alias base="TP90pct6hr">tp90pct6hr</alias>
|
||||
<alias base="ThP1hr">thp1hr</alias>
|
||||
<alias base="DRYTPPROB3hr">drytpprob3hr</alias>
|
||||
<alias base="WGS50pct">wgs50pct</alias>
|
||||
<alias base="WS50pct">ws50pct</alias>
|
||||
<alias base="Vis50pct">vis50pct</alias>
|
||||
<alias base="T50pct">t50pct</alias>
|
||||
<alias base="PMSL10pct">pmsl10pct</alias>
|
||||
<alias base="PMSL50pct">pmsl50pct</alias>
|
||||
<alias base="PMSL90pct">pmsl90pct</alias>
|
||||
<alias base="CC">cc</alias>
|
||||
<alias base="MaxTW">maxtw</alias>
|
||||
<alias base="LLWSHgt">llwshgt</alias>
|
||||
</aliasList>
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
# Jul 17, 2017 DR19976 MPorricelli Add labeling of Probability Matched Mean fields#
|
||||
# Nov 29, 2017 6536 bsteffen Handle redundant statistical specifiers better.
|
||||
# Feb 07, 2018 7213 nabowle Only allow P-ETSS to create Statistical parameters.
|
||||
# Mar 19, 2018 20395 wkwock Added PDS template 15
|
||||
#
|
||||
|
||||
import grib2
|
||||
|
@ -444,7 +445,7 @@ class GribDecoder():
|
|||
# Templates 0-11 are ordered the same for the most part and can therefore be processed the same
|
||||
# Exception cases are handled accordingly
|
||||
|
||||
if pdsTemplateNumber <= 12:
|
||||
if pdsTemplateNumber <= 12 or pdsTemplateNumber == 15:
|
||||
|
||||
# Get the basic level and parameter information
|
||||
if (pdsTemplate[0] == 255):
|
||||
|
@ -477,7 +478,13 @@ class GribDecoder():
|
|||
|
||||
levelName = None;
|
||||
levelUnit = None;
|
||||
gribLevel = GribTableLookup.getInstance().getTableValue(centerID, subcenterID, LEVELS_TABLE, int(pdsTemplate[9]))
|
||||
|
||||
#In case the 1st level is 'SFC' and the 2nd level is 'FHAG', use FHAG as the level number
|
||||
levelNumber = int(pdsTemplate[9])
|
||||
levelNumber2 = int(pdsTemplate[12])
|
||||
if levelNumber == 1 and levelNumber2 == 103:
|
||||
levelNumber = levelNumber2
|
||||
gribLevel = GribTableLookup.getInstance().getTableValue(centerID, subcenterID, LEVELS_TABLE, levelNumber)
|
||||
|
||||
if gribLevel is not None:
|
||||
levelName = gribLevel.getAbbreviation();
|
||||
|
@ -519,10 +526,7 @@ class GribDecoder():
|
|||
else:
|
||||
levelTwoValue = float(pdsTemplate[14] * pow(10, pdsTemplate[13] * -1))
|
||||
|
||||
if levelName == 'SFC' and levelOneValue != float(0):
|
||||
levelOneValue = float(0)
|
||||
|
||||
if levelName == 'EATM':
|
||||
if levelName == 'EATM' or levelName == 'SFC':
|
||||
levelOneValue = float(0)
|
||||
levelTwoValue = float(Level.getInvalidLevelValue())
|
||||
|
||||
|
|
|
@ -111,6 +111,8 @@ import ucar.unidata.io.RandomAccessFile;
|
|||
* Apr 11, 2016 5564 bsteffen Move localization files to common_static
|
||||
* Apr 19, 2016 5572 bsteffen Move GribModelLookup to common
|
||||
* Sep 11, 2017 6406 bsteffen Upgrade ucar
|
||||
* Aug 02, 2018 7397 mapeters Fix parameter table lookups so standard
|
||||
* ucar lookups are used
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
|
@ -159,25 +161,21 @@ public class Grib1Decoder {
|
|||
LocalizationLevel.BASE),
|
||||
"/grib/ucar/userTables.lst")
|
||||
.getPath();
|
||||
Grib1ParamTables tables;
|
||||
try {
|
||||
Grib1ParamTables.Lookup lookup = new Grib1ParamTables.Lookup();
|
||||
lookup.readLookupTable(ucarUserFile);
|
||||
tables = new Grib1ParamTables(lookup, null);
|
||||
Grib1ParamTables.addParameterTableLookup(ucarUserFile);
|
||||
} catch (IOException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error reading user parameter tables for ucar grib decoder",
|
||||
e);
|
||||
tables = new Grib1ParamTables(null, null);
|
||||
}
|
||||
paramTables = tables;
|
||||
paramTables = new Grib1ParamTables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the grib file provided.
|
||||
*
|
||||
* @param gribFileName
|
||||
* The name of the file to be decoded
|
||||
* @param message
|
||||
* message describing the grib file to decode
|
||||
* @return The decoded GridRecords
|
||||
* @throws GribException
|
||||
* If decoding the file fails or encounters problems
|
||||
|
|
|
@ -71,6 +71,36 @@
|
|||
</process>
|
||||
</model>
|
||||
|
||||
<!--
|
||||
DThP3hr is repackaged from SPC.
|
||||
-->
|
||||
<model>
|
||||
<name>NationalBlend</name>
|
||||
<center>7</center>
|
||||
<subcenter>9</subcenter>
|
||||
<grids>
|
||||
<id>NBMv3</id>
|
||||
</grids>
|
||||
<process>
|
||||
<id>113</id>
|
||||
</process>
|
||||
</model>
|
||||
|
||||
<!--
|
||||
Fosberg Fire Weather Index (mxffwi) is repackaged from SPC.
|
||||
-->
|
||||
<model>
|
||||
<name>NationalBlend</name>
|
||||
<center>7</center>
|
||||
<subcenter>14</subcenter>
|
||||
<grids>
|
||||
<id>NBMv3</id>
|
||||
</grids>
|
||||
<process>
|
||||
<id>104</id>
|
||||
</process>
|
||||
</model>
|
||||
|
||||
<!--Alaska-->
|
||||
<model>
|
||||
<name>NationalBlendAK</name>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
1:1:Fire Outlook Due to Dry Thunderstorm:index(see GRIB 2 code table 4.224):FIREODT
|
||||
2:2:Haines Index:Numeric:HINDEX
|
||||
3:3:Haines Index:Numeric:HINDEX
|
||||
4:4:Fosberg Index:Numeric:FOSINDX
|
||||
#192-254 Reserved for local use
|
||||
255:255:Missing
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
# Product Discipline 0: Meteorological products, Parameter Category 1: Moisture
|
||||
#192-254 Reserved for local use
|
||||
220:220:SnowRatio::SNOWRATIO
|
||||
228:228:Flat Ice Accumulation (FRAM):kg m-2:FICEAC
|
||||
231:231:Precipitation Potential Index (PPI):%:PPI
|
||||
232:232:Probability Cloud Ice Present:%:PRBCLDICE
|
||||
233:233:Snow Liquid ratio:kg kg-1:SNOWRATIO
|
||||
242:242:Probability of Cloud Ice Present:%:PRBCLDICE
|
||||
243:243:Precipitation Potential Index (PPI):%:PPI
|
||||
255:255:Missing
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# Product Discipline 0: Meteorological products, Parameter Category 19: Physical atmospheric properties
|
||||
3:3:Mixed Layer Depth:m:MIXHT
|
||||
#192-254 Reserved for local use
|
||||
192:192:Maximum Snow Albedo:%:MXSALB
|
||||
193:193:Snow-Free Albedo:%:SNFALB
|
||||
|
@ -44,5 +45,6 @@
|
|||
233:233:Icing probability:non-dim:ICPRB
|
||||
234:234:Icing severity:non-dim:ICSEV
|
||||
235:235:Snow Level:m:SNOWLVL
|
||||
236:236:Snow Level:m:SNOWLVL
|
||||
255:255:Missing
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Product Discipline 0: Meteorological products, Parameter Category 2: Momentum
|
||||
# 192-254 Reserved for local use
|
||||
192:192:Vertical speed shear:s^-1:VWSH:VSS
|
||||
192:192:Vertical speed sheer:s^-1:VWSH:VSS
|
||||
193:193:Horizontal Momentum Flux:N/m^2:MFLX
|
||||
194:194:U-Component Storm Motion:m/s:USTM
|
||||
195:195:V-Component Storm Motion:m/s:VSTM
|
||||
|
@ -10,8 +10,8 @@
|
|||
199:199:Longitude of U Wind Component of Velocity:degrees:LOUV
|
||||
200:200:Latitude of V Wind Component of Velocity:degrees:LAVV
|
||||
201:201:Longitude of V Wind Component of Velocity:degrees:LOVV
|
||||
202:202:Latitude of Pressure Point:degrees:LAPP
|
||||
203:203:Longitude of Pressure Point:degrees:LOPP
|
||||
202:202:Latitude of Presure Point:degrees:LAPP
|
||||
203:203:Longitude of Presure Point:degrees:LOPP
|
||||
204:204:Vertical Eddy Diffusivity Heat exchange:m^2/s:VEDH
|
||||
205:205:Covariance between Meridional and Zonal Components of the wind.:m^2/s^2:COVMZ
|
||||
206:206:Covariance between Temperature and Zonal Components of the wind.:K*m/s:COVTZ
|
||||
|
@ -33,4 +33,6 @@
|
|||
222:222:U Component of Hourly Maximum 10m Wind Speed:m/s:MAXUW
|
||||
223:223:V Component of Hourly Maximum 10m Wind Speed:m/s:MAXVW
|
||||
224:224:Ventilation Rate:m^2/s:VRATE
|
||||
225:225:Transport Wind Speed:m/s:TRWSPD
|
||||
226:226:Transport Wind Direction:Deg:TRWDIR
|
||||
255:255:Missing
|
||||
|
|
|
@ -10,5 +10,8 @@
|
|||
197:197:Updraft Helicity:m^2/s^2:UPHL
|
||||
198:198:Leaf Area Index::LAI
|
||||
199:199:Hourly Maximum of Updraft Helicity over Layer 2km to 5 km AGL:m^2/s^2:MXUPHL
|
||||
201:201:Bourgoiun Negative Energy Layer (surface to freezing level):J/kg:NBE
|
||||
202:202:Bourgoiun Positive Energy Layer (2k ft AGL to 400 hPa):J/kg:PBE
|
||||
|
||||
255:255:Missing
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#192-254 Reserved for local use
|
||||
192:192:Level at Specified Pressure Difference from Ground to Level:Pa:PDLY:LYRBL
|
||||
193:193:Eta Level:Eta value:ELYR:ETA
|
||||
200:200:Entire Atmosphere::NONE:EA
|
||||
200:200:Entire Atmosphere::EA
|
||||
201:201:Entire Ocean::NONE
|
||||
204:204:Highest Tropospheric Freezing Level::HTFL
|
||||
206:206:Grid Scale Cloud Bottom Level::GSCBL
|
||||
|
|
|
@ -43,5 +43,6 @@
|
|||
232:232:Volcanic Ash Forecast Transport and Dispersion:log10(kg/m^3):VAFTD
|
||||
233:233:Icing probability:non-dim:ICPRB
|
||||
234:234:Icing severity:non-dim:ICSEV
|
||||
237:237:Dry Thunderstorm Probability:%:DRYTPROB
|
||||
255:255:Missing
|
||||
|
||||
|
|
|
@ -652,6 +652,9 @@ TW_NBM-NCEP-MDL MaxTW
|
|||
CAPE_NBM-NCEP-MDL PBE
|
||||
CIn_NBM-NCEP-MDL NBE
|
||||
PRBCLDICE-9.999e+18%_NBM-NCEP-MDL PrbCldIce
|
||||
PRBCLDICE0.0%_NBM-NCEP-MDL PrbCldIce
|
||||
GeH_NBM-NCEP-MDL LLWSHgt
|
||||
DRYTPROB0.0%_NBM-NCEP-MDL DRYTPPROB
|
||||
// NBM publishes this, it is marked SREF because NBM doesn't change it.
|
||||
ThP0.0%_SREF-NCEP-MDL_2345x1597_10800-0 ThP3hr
|
||||
//END NationalBLend
|
||||
|
|
|
@ -103,7 +103,6 @@ import com.vividsolutions.jts.io.WKTWriter;
|
|||
* Sep 17, 2015 4756 dhladky Multiple guidance source bugs.
|
||||
* Feb 12, 2016 5370 dhladky Camel case for insertTime.
|
||||
* Apr 07, 2016 5491 tjensen Fix NullPointerException from getRawGeometries
|
||||
* Mar 07, 2017 DR 11861 lshi FFMP use of QPF in Basin Table
|
||||
* May 11, 2017 6266 nabowle Use GetRadarSpatialRequest in getRadarCenter().
|
||||
* </pre>
|
||||
*
|
||||
|
@ -1302,18 +1301,13 @@ public class FFMPUtils {
|
|||
* Gets the ratio value
|
||||
*
|
||||
* @param qpe
|
||||
* @param qpf
|
||||
* @param guid
|
||||
* @return
|
||||
*/
|
||||
public static float getRatioValue(float qpe, float qpf, float guid) {
|
||||
public static float getRatioValue(float qpe, float guid) {
|
||||
float value = Float.NaN;
|
||||
if ((qpe >= 0.0f) && (guid >= 0.0f)) {
|
||||
value = qpe;
|
||||
if ( !Float.isNaN(qpf)){
|
||||
value += qpf;
|
||||
}
|
||||
value = (float) ((value / guid) * 100.0);
|
||||
value = (float) ((qpe / guid) * 100.0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1323,21 +1317,18 @@ public class FFMPUtils {
|
|||
* find max ratio in list
|
||||
*
|
||||
* @param qpes
|
||||
* @param qpfs
|
||||
* @param guids
|
||||
* @return
|
||||
*/
|
||||
public static float getMaxRatioValue(List<Float> qpes, List<Float> qpfs, List<Float> guids) {
|
||||
public static float getMaxRatioValue(List<Float> qpes, List<Float> guids) {
|
||||
float ratio = Float.NaN;
|
||||
|
||||
boolean hasQpfs = qpfs != null && qpfs.size() == qpes.size();
|
||||
if ((qpes.size() == guids.size()) && (!qpes.isEmpty())
|
||||
&& (!guids.isEmpty())) {
|
||||
for (int i = 0; i < qpes.size(); i++) {
|
||||
if (guids.get(i) > 0.0f) {
|
||||
float qpf = hasQpfs ? qpfs.get(i): Float.NaN;
|
||||
float nratio = getRatioValue(qpes.get(i), qpf, guids.get(i));
|
||||
if ((!Float.isNaN(nratio) &&(nratio > ratio))
|
||||
float nratio = getRatioValue(qpes.get(i), guids.get(i));
|
||||
if (((nratio > ratio) && !Float.isNaN(nratio))
|
||||
|| Float.isNaN(ratio)) {
|
||||
if (!Float.isInfinite(nratio)) {
|
||||
ratio = nratio;
|
||||
|
@ -1355,19 +1346,17 @@ public class FFMPUtils {
|
|||
* Gets the diff value
|
||||
*
|
||||
* @param qpe
|
||||
* @param qpf
|
||||
* @param guid
|
||||
* @return
|
||||
*/
|
||||
public static float getDiffValue(float qpe, float qpf, float guid) {
|
||||
public static float getDiffValue(float qpe, float guid) {
|
||||
float value = Float.NaN;
|
||||
|
||||
if ((qpe >= 0.0f) && (guid >= 0.0f)) {
|
||||
value = qpe;
|
||||
if ( !Float.isNaN(qpf)){
|
||||
value += qpf;
|
||||
}
|
||||
value -= guid;
|
||||
float qpeRnd = Float.parseFloat(formatter.format(qpe));
|
||||
float guidRnd = Float.parseFloat(formatter.format(guid));
|
||||
value = new Float(qpeRnd - guidRnd);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1379,22 +1368,19 @@ public class FFMPUtils {
|
|||
* find max diff in the list
|
||||
*
|
||||
* @param qpes
|
||||
* @param qpfs
|
||||
* @param guids
|
||||
* @return
|
||||
*/
|
||||
public static float getMaxDiffValue(List<Float> qpes, List<Float> qpfs, List<Float> guids) {
|
||||
public static float getMaxDiffValue(List<Float> qpes, List<Float> guids) {
|
||||
float diff = Float.NaN;
|
||||
|
||||
boolean hasQpfs = qpfs != null && qpfs.size() == qpes.size();
|
||||
if ((qpes.size() == guids.size()) && (!qpes.isEmpty())
|
||||
&& (!guids.isEmpty())) {
|
||||
|
||||
for (int i = 0; i < qpes.size(); i++) {
|
||||
if (guids.get(i) > 0.0f) {
|
||||
float qpf = hasQpfs ? qpfs.get(i): Float.NaN;
|
||||
float ndiff = getDiffValue(qpes.get(i), qpf, guids.get(i));
|
||||
if ((!Float.isNaN(ndiff) && (ndiff > diff))
|
||||
float ndiff = getDiffValue(qpes.get(i), guids.get(i));
|
||||
if ((((ndiff) > diff) && !Float.isNaN(ndiff))
|
||||
|| Float.isNaN(diff)) {
|
||||
diff = ndiff;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='50.0' pixelValue='0'/>
|
||||
<entry displayValue='55.0' pixelValue='17'/>
|
||||
|
@ -313,7 +313,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='1.0' pixelValue='17'/>
|
||||
|
@ -341,7 +341,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='1.0' pixelValue='17'/>
|
||||
|
@ -368,7 +368,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
@ -395,7 +395,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
@ -423,7 +423,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
@ -450,7 +450,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
@ -477,7 +477,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
@ -505,7 +505,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
@ -532,7 +532,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
@ -559,7 +559,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
@ -586,7 +586,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
@ -613,7 +613,7 @@ ARIFFG100, then the style rule parameter tag will look like this example....
|
|||
</paramLevelMatches>
|
||||
<imageStyle>
|
||||
<displayUnits>in</displayUnits>
|
||||
<defaultColormap>Grid/gridded data</defaultColormap>
|
||||
<defaultColormap>Grid/Gridded Data</defaultColormap>
|
||||
<dataMapping>
|
||||
<entry displayValue='0.0' pixelValue='0'/>
|
||||
<entry displayValue='2.0' pixelValue='17'/>
|
||||
|
|
|
@ -30,6 +30,8 @@ import javax.persistence.SequenceGenerator;
|
|||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.hibernate.annotations.Index;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.NullUtil;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURI;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.NullString;
|
||||
|
@ -60,6 +62,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|||
* Aug 03, 2016 4360 rferrel Add name to unique constraint.
|
||||
* Made datasetId, secondaryId, ensembleId, non-nullable.
|
||||
* Now use EMPTY_STRING for null values and created static nullValue_ methods
|
||||
* Aug 03, 2018 7424 tjensen Add index to GridCoverage location
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -67,9 +70,10 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|||
* @version 1.0
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "grid_info", uniqueConstraints = { @UniqueConstraint(name = "uk_grid_info_datauri_fields", columnNames = {
|
||||
"datasetid", "parameter_abbreviation", "level_id", "secondaryid",
|
||||
"ensembleid", "location_id" }) })
|
||||
@Table(name = "grid_info", uniqueConstraints = {
|
||||
@UniqueConstraint(name = "uk_grid_info_datauri_fields", columnNames = {
|
||||
"datasetid", "parameter_abbreviation", "level_id",
|
||||
"secondaryid", "ensembleid", "location_id" }) })
|
||||
@SequenceGenerator(name = "GRIDINFO_GENERATOR", sequenceName = "gridinfo_seq", allocationSize = 1)
|
||||
@DynamicSerialize
|
||||
public class GridInfoRecord extends PersistableDataObject<Integer> {
|
||||
|
@ -109,6 +113,7 @@ public class GridInfoRecord extends PersistableDataObject<Integer> {
|
|||
@ManyToOne(optional = false)
|
||||
@PrimaryKeyJoinColumn
|
||||
@DataURI(position = 3, converter = GridCoverageConverter.class)
|
||||
@Index(name = "grid_info_location_id_index")
|
||||
@DynamicSerializeElement
|
||||
private GridCoverage location;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.raytheon.uf.common.style.level.SingleLevel;
|
|||
* Jul 30, 2007 chammack Initial Creation.
|
||||
* May 01, 2014 DCS 027 MPorricelli Add WBZ level
|
||||
* Aug 15, 2016 5821 bsteffen Add TROP level
|
||||
* May 18, 2018 20395 wkwock Add CBL and CLG level
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -86,6 +87,10 @@ public class GridLevelTranslator {
|
|||
level = new SingleLevel(Level.LevelType.FRZ);
|
||||
} else if (levelType.equalsIgnoreCase("WBZ")) {
|
||||
level = new SingleLevel(Level.LevelType.WBZ);
|
||||
} else if (levelType.equalsIgnoreCase("CBL")) {
|
||||
level = new SingleLevel(Level.LevelType.CBL);
|
||||
} else if (levelType.equalsIgnoreCase("CLG")) {
|
||||
level = new SingleLevel(Level.LevelType.CLG);
|
||||
} else {
|
||||
return new SingleLevel(Level.LevelType.DEFAULT);
|
||||
}
|
||||
|
|
|
@ -4978,4 +4978,61 @@ in | .03937 | 0 | 4 | | |..|8000F0FF| | 16 | \
|
|||
</contourLabeling>
|
||||
</contourStyle>
|
||||
</styleRule>
|
||||
<styleRule>
|
||||
<paramLevelMatches>
|
||||
<parameter>LLWSHgt</parameter>
|
||||
</paramLevelMatches>
|
||||
<contourStyle>
|
||||
<displayUnits label="hft">ft*100.0</displayUnits>
|
||||
<contourLabeling labelSpacing="4" maxLabel="." minMaxLabelFormat="#0">
|
||||
<values>5 10 15 20</values>
|
||||
</contourLabeling>
|
||||
</contourStyle>
|
||||
</styleRule>
|
||||
<styleRule>
|
||||
<paramLevelMatches>
|
||||
<singleLevel units="CBL" />
|
||||
<parameter>CC</parameter>
|
||||
</paramLevelMatches>
|
||||
<contourStyle>
|
||||
<displayUnits label="hft">ft*100.0</displayUnits>
|
||||
<contourLabeling labelSpacing="4">
|
||||
<values>0 1 2 6 10 20 31 100 200</values>
|
||||
</contourLabeling>
|
||||
</contourStyle>
|
||||
</styleRule>
|
||||
<styleRule>
|
||||
<paramLevelMatches>
|
||||
<singleLevel units="CLG" />
|
||||
<parameter>CC</parameter>
|
||||
</paramLevelMatches>
|
||||
<contourStyle>
|
||||
<displayUnits label="ft">ft</displayUnits>
|
||||
<contourLabeling labelSpacing="6">
|
||||
<values>0 100 200 600 1000 2000 3100 10000 20000</values>
|
||||
</contourLabeling>
|
||||
</contourStyle>
|
||||
</styleRule>
|
||||
<styleRule>
|
||||
<paramLevelMatches>
|
||||
<parameter>MIXHT</parameter>
|
||||
</paramLevelMatches>
|
||||
<contourStyle>
|
||||
<displayUnits>m</displayUnits>
|
||||
<contourLabeling labelSpacing="4">
|
||||
<increment>1</increment>
|
||||
</contourLabeling>
|
||||
</contourStyle>
|
||||
</styleRule>
|
||||
<styleRule>
|
||||
<paramLevelMatches>
|
||||
<parameter>HTSGW</parameter>
|
||||
</paramLevelMatches>
|
||||
<contourStyle>
|
||||
<displayUnits>ft</displayUnits>
|
||||
<contourLabeling labelSpacing="4">
|
||||
<increment>1</increment>
|
||||
</contourLabeling>
|
||||
</contourStyle>
|
||||
</styleRule>
|
||||
</styleRuleset>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,3 +24,4 @@ Export-Package: com.raytheon.uf.common.dataplugin.satellite,
|
|||
com.raytheon.uf.common.dataplugin.satellite.units.goes.convert,
|
||||
com.raytheon.uf.common.dataplugin.satellite.units.ir,
|
||||
com.raytheon.uf.common.dataplugin.satellite.units.water
|
||||
Import-Package: com.raytheon.uf.common.status
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
import javax.measure.unit.Unit;
|
||||
import javax.measure.unit.UnitFormat;
|
||||
|
||||
|
@ -38,10 +39,15 @@ import com.raytheon.uf.common.dataaccess.exception.DataRetrievalException;
|
|||
import com.raytheon.uf.common.dataaccess.exception.InvalidIdentifiersException;
|
||||
import com.raytheon.uf.common.dataaccess.impl.AbstractGridDataPluginFactory;
|
||||
import com.raytheon.uf.common.dataaccess.impl.DefaultGridData;
|
||||
import com.raytheon.uf.common.dataaccess.util.DataWrapperUtil;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.units.SatelliteUnits;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.units.SatelliteUnitsUtil;
|
||||
import com.raytheon.uf.common.dataquery.requests.RequestConstraint;
|
||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||
import com.raytheon.uf.common.geospatial.data.UnitConvertingDataFilter;
|
||||
import com.raytheon.uf.common.geospatial.util.SubGridGeometryCalculator;
|
||||
import com.raytheon.uf.common.numeric.source.DataSource;
|
||||
|
||||
/**
|
||||
|
@ -70,6 +76,8 @@ import com.raytheon.uf.common.numeric.source.DataSource;
|
|||
* Aug 01, 2016 2416 tgurney Add dataURI as optional identifier
|
||||
* Mar 06, 2017 6142 bsteffen Remove dataURI as optional identifier
|
||||
* Aug 29, 2017 6389 bsteffen Ensure location names are unique.
|
||||
* Jul 31, 2018 6389 mapeters Override getDataSource() to handle unit
|
||||
* conversion for GOES-R
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -223,6 +231,32 @@ public class SatelliteGridFactory extends AbstractGridDataPluginFactory {
|
|||
return idValStrings.toArray(new String[idValues.length]);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSource getDataSource(PluginDataObject pdo,
|
||||
SubGridGeometryCalculator subGrid) {
|
||||
IDataRecord dataRecord = getDataRecord(pdo, subGrid);
|
||||
if (dataRecord == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get converter from data unit to record unit
|
||||
Unit<?> recordUnit = SatelliteUnitsUtil
|
||||
.getRecordUnit((SatelliteRecord) pdo);
|
||||
if (recordUnit == null) {
|
||||
recordUnit = Unit.ONE;
|
||||
}
|
||||
Unit<?> dataUnit = SatelliteUnitsUtil.getDataUnit(recordUnit,
|
||||
dataRecord);
|
||||
UnitConverter converter = dataUnit.getConverterTo(recordUnit);
|
||||
|
||||
// Construct unit-converting data source
|
||||
DataSource dataSource = DataWrapperUtil
|
||||
.constructArrayWrapper(dataRecord, false);
|
||||
dataSource = UnitConvertingDataFilter.apply(dataSource, converter);
|
||||
return dataSource;
|
||||
|
||||
}
|
||||
|
||||
protected static String generateLocationName(
|
||||
SatelliteRecord satelliteRecord) {
|
||||
StringBuilder locationName = new StringBuilder(32);
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.common.dataplugin.satellite.units;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.measure.unit.Unit;
|
||||
import javax.measure.unit.UnitFormat;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.units.goes.PolarPrecipWaterPixel;
|
||||
import com.raytheon.uf.common.dataplugin.satellite.units.water.BlendedTPWPixel;
|
||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
||||
/**
|
||||
* Utility class for dealing with satellite record units.
|
||||
*
|
||||
* <pre>
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ------- ----------- -------------------------------------------
|
||||
* Jul 31, 2018 6389 mapeters Initial creation (extracted from
|
||||
* SatDataRetriever)
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mapeters
|
||||
*/
|
||||
public class SatelliteUnitsUtil {
|
||||
|
||||
private static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(SatelliteUnitsUtil.class);
|
||||
|
||||
private static final String DMSP = "DMSP";
|
||||
|
||||
private static final String POES = "POES-NPOESS";
|
||||
|
||||
private static final String MISC = "Miscellaneous";
|
||||
|
||||
private static final String PRECIP = "Sounder Based Derived Precipitable Water (PW)";
|
||||
|
||||
/**
|
||||
* Extracts the record units from the given satellite record
|
||||
*
|
||||
* @param record
|
||||
* @return the record units
|
||||
*/
|
||||
public static Unit<?> getRecordUnit(SatelliteRecord record) {
|
||||
Unit<?> recordUnit = null;
|
||||
String physicalElement = record.getPhysicalElement();
|
||||
|
||||
if (record.getUnits() != null && !record.getUnits().isEmpty()) {
|
||||
try {
|
||||
recordUnit = UnitFormat.getUCUMInstance().parseProductUnit(
|
||||
record.getUnits(), new ParsePosition(0));
|
||||
} catch (ParseException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Unable to parse satellite units: " + record.getUnits(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
if (physicalElement.equals(PRECIP)) {
|
||||
String creatingEntity = record.getCreatingEntity();
|
||||
if (creatingEntity.equals(DMSP) || creatingEntity.equals(POES)) {
|
||||
recordUnit = new PolarPrecipWaterPixel();
|
||||
} else if (creatingEntity.equals(MISC)) {
|
||||
recordUnit = new BlendedTPWPixel();
|
||||
}
|
||||
}
|
||||
|
||||
return recordUnit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the data units for the data record given the PDO's base unit
|
||||
*
|
||||
* @param recordUnit
|
||||
* @param dataRecord
|
||||
* @return
|
||||
*/
|
||||
public static Unit<?> getDataUnit(Unit<?> recordUnit,
|
||||
IDataRecord dataRecord) {
|
||||
Unit<?> units = recordUnit != null ? recordUnit : Unit.ONE;
|
||||
Map<String, Object> attrs = dataRecord.getDataAttributes();
|
||||
if (attrs != null) {
|
||||
Number offset = (Number) attrs.get(SatelliteRecord.SAT_ADD_OFFSET);
|
||||
Number scale = (Number) attrs.get(SatelliteRecord.SAT_SCALE_FACTOR);
|
||||
|
||||
if (offset != null) {
|
||||
double offsetVal = offset.doubleValue();
|
||||
if (offsetVal != 0.0) {
|
||||
units = units.plus(offsetVal);
|
||||
}
|
||||
}
|
||||
if (scale != null) {
|
||||
double scaleVal = scale.doubleValue();
|
||||
if (scaleVal != 0.0) {
|
||||
units = units.times(scaleVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
return units;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not the data within the given record is signed
|
||||
*
|
||||
* @param record
|
||||
* @return whether or not record's data is signed
|
||||
*/
|
||||
public static boolean isSigned(IDataRecord record) {
|
||||
Map<String, Object> attrs = record.getDataAttributes();
|
||||
if (attrs != null) {
|
||||
Boolean signed = (Boolean) attrs
|
||||
.get(SatelliteRecord.SAT_SIGNED_FLAG);
|
||||
if (signed != null && signed) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ package com.raytheon.uf.common.dataplugin.shef.tables;
|
|||
|
||||
// Generated Oct 17, 2008 2:22:17 PM by Hibernate Tools 3.2.2.GA
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.AttributeOverride;
|
||||
|
@ -32,6 +31,8 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.FetchType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
|
@ -49,19 +50,22 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 17, 2008 Initial generation by hbm2java
|
||||
* Aug 19, 2011 10672 jkorman Move refactor to new project
|
||||
* Oct 07, 2013 2361 njensen Removed XML annotations
|
||||
* Sep 26, 2016 5631 bkowal Cleanup.
|
||||
* Aug 19, 2011 10672 jkorman Move refactor to new project
|
||||
* Oct 07, 2013 2361 njensen Removed XML annotations
|
||||
* Sep 26, 2016 5631 bkowal Cleanup.
|
||||
* Jul 25, 2018 5588 mapeters Added NamedQueries annotation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jkorman
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = Dhrradar.SELECT_BY_RAD_ID_BETWEEN_OBS_TIME, query = Dhrradar.SELECT_BY_RAD_ID_BETWEEN_OBS_TIME_HQL) })
|
||||
@Entity
|
||||
@Table(name = "dhrradar")
|
||||
@DynamicSerialize
|
||||
public class Dhrradar extends PersistableDataObject<DhrradarId>
|
||||
implements Serializable, IGriddedRadarRecord {
|
||||
implements IGriddedRadarRecord {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
@ -139,8 +143,8 @@ public class Dhrradar extends PersistableDataObject<DhrradarId>
|
|||
|
||||
@EmbeddedId
|
||||
@AttributeOverrides({
|
||||
@AttributeOverride(name = "radid", column = @Column(name = "radid", nullable = false, length = 3) ),
|
||||
@AttributeOverride(name = "obstime", column = @Column(name = "obstime", nullable = false, length = 29) ) })
|
||||
@AttributeOverride(name = "radid", column = @Column(name = "radid", nullable = false, length = 3)),
|
||||
@AttributeOverride(name = "obstime", column = @Column(name = "obstime", nullable = false, length = 29)) })
|
||||
public DhrradarId getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.common.dataplugin.shef.tables;
|
||||
// default package
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
// Generated Oct 17, 2008 2:22:17 PM by Hibernate Tools 3.2.2.GA
|
||||
|
||||
|
@ -34,12 +31,15 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.FetchType;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.NamedQueries;
|
||||
import javax.persistence.NamedQuery;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.persist.PersistableDataObject;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||
|
||||
/**
|
||||
|
@ -52,19 +52,22 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 17, 2008 Initial generation by hbm2java
|
||||
* Aug 19, 2011 10672 jkorman Move refactor to new project
|
||||
* Oct 07, 2013 2361 njensen Removed XML annotations
|
||||
* Nov 21, 2016 5588 nabowle Cleanup.
|
||||
* Aug 19, 2011 10672 jkorman Move refactor to new project
|
||||
* Oct 07, 2013 2361 njensen Removed XML annotations
|
||||
* Nov 21, 2016 5588 nabowle Cleanup.
|
||||
* Jul 25, 2018 5588 mapeters Added NamedQueries annotation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author jkorman
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name = Dspradar.SELECT_BY_RAD_ID_BETWEEN_OBS_TIME, query = Dspradar.SELECT_BY_RAD_ID_BETWEEN_OBS_TIME_HQL) })
|
||||
@Entity
|
||||
@Table(name = "dspradar")
|
||||
@com.raytheon.uf.common.serialization.annotations.DynamicSerialize
|
||||
@DynamicSerialize
|
||||
public class Dspradar extends PersistableDataObject<DspradarId>
|
||||
implements Serializable, IGriddedRadarRecord {
|
||||
implements IGriddedRadarRecord {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
@ -287,6 +290,7 @@ public class Dspradar extends PersistableDataObject<DspradarId>
|
|||
this.JEndTime = JEndTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Column(name = "mean_field_bias")
|
||||
public Short getMeanFieldBias() {
|
||||
return this.meanFieldBias;
|
||||
|
@ -305,6 +309,7 @@ public class Dspradar extends PersistableDataObject<DspradarId>
|
|||
this.sampleSize = sampleSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Column(name = "grid_filename", length = 20)
|
||||
public String getGridFilename() {
|
||||
return this.gridFilename;
|
||||
|
|
|
@ -41,11 +41,12 @@ import com.raytheon.uf.common.ohd.AppsDefaults;
|
|||
* May 13, 2016 5576 bkowal Updated to be more of a general utility for
|
||||
* Apps_Defaults property conversions.
|
||||
* Jun 13, 2016 5576 bkowal Added {@link #parallelExecEnabled()}.
|
||||
* Jun 29, 2016 5576 bkowal Added a TODO explaning future steps.
|
||||
* Jun 29, 2016 5576 bkowal Added a todo explaining future steps.
|
||||
* Jul 12, 2016 4619 bkowal Relocated to common.
|
||||
* Aug 10, 2016 4619 bkowal The parallel write flag is now a constant to
|
||||
* ensure it is not accidentally overwritten.
|
||||
* Aug 07, 2017 6334 bkowal Directories are now created with 770 permissions and files 660.
|
||||
* Jul 19, 2018 5588 mapeters Added {@link #getPathForTokenWithoutCreating(String)}
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -76,16 +77,18 @@ public final class AppsDefaultsConversionWrapper {
|
|||
|
||||
/**
|
||||
* Retrieves a {@link Path} associated with an Apps_Defaults token. Will
|
||||
* also verify that that Path exists and make any required standard
|
||||
* modifications to the Path before returning it.
|
||||
* also make any required standard modifications to the Path before
|
||||
* returning it.
|
||||
*
|
||||
* Note that the path will NOT be created if it doesn't exist. See
|
||||
* {@link #getPathForToken(String)} if it should be created in this case.
|
||||
*
|
||||
* @param token
|
||||
* the specified Apps_Defaults token.
|
||||
* @return the {@link Path} associated with the specified token.
|
||||
* @throws AppsDefaultsPathException
|
||||
* @return the {@link Path} associated with the specified token, which may
|
||||
* not exist.
|
||||
*/
|
||||
public static Path getPathForToken(final String token)
|
||||
throws AppsDefaultsPathException {
|
||||
public static Path getPathForTokenWithoutCreating(final String token) {
|
||||
final String directory = AppsDefaults.getInstance().getToken(token);
|
||||
if (directory == null) {
|
||||
throw new IllegalArgumentException("No " + AppsDefaults.NAME
|
||||
|
@ -99,6 +102,29 @@ public final class AppsDefaultsConversionWrapper {
|
|||
+ PARALLEL_DIRECTORY;
|
||||
directoryPath = Paths.get(destinationRoot, destinationDirectory);
|
||||
}
|
||||
|
||||
return directoryPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a {@link Path} associated with an Apps_Defaults token. Will
|
||||
* also make any required standard modifications to the Path before
|
||||
* returning it.
|
||||
*
|
||||
* Note that the path will be created if it doesn't exist. See
|
||||
* {@link #getPathForTokenWithoutCreating(String)} if it doesn't need to be
|
||||
* created.
|
||||
*
|
||||
* @param token
|
||||
* the specified Apps_Defaults token.
|
||||
* @return the {@link Path} associated with the specified token, which is
|
||||
* guaranteed to exist.
|
||||
* @throws AppsDefaultsPathException
|
||||
* if an I/O error occurs when trying to create the path
|
||||
*/
|
||||
public static Path getPathForToken(final String token)
|
||||
throws AppsDefaultsPathException {
|
||||
Path directoryPath = getPathForTokenWithoutCreating(token);
|
||||
if (!Files.exists(directoryPath)) {
|
||||
try {
|
||||
com.raytheon.uf.common.util.file.Files.createDirectories(
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<bean id="dhrDecodeSrv" class="com.raytheon.uf.edex.ohd.pproc.HPEDhrSrv" />
|
||||
|
||||
<bean id="dhrGather" class="com.raytheon.uf.edex.plugin.mpe.gather.dhr.DHRGather" />
|
||||
<bean id="dspGather" class="com.raytheon.uf.edex.plugin.mpe.gather.dsp.DSPGather" />
|
||||
|
||||
<bean id="dhrDecoder"
|
||||
class="com.raytheon.uf.edex.plugin.mpe.gather.dhr.DHRDecoder" />
|
||||
|
@ -21,10 +22,19 @@
|
|||
<constructor-arg value="jms-durable:queue:Ingest.dhr" />
|
||||
</bean>
|
||||
|
||||
<camelContext id="nonClusteredDHRroutes"
|
||||
<bean id="dhrRadarServerDistRegistry" factory-bean="radarserverDistributionSrv"
|
||||
factory-method="register">
|
||||
<constructor-arg value="dhr" />
|
||||
<constructor-arg value="jms-durable:queue:Ingest.dhr" />
|
||||
</bean>
|
||||
|
||||
<!-- DHR and DSP files both come in from Ingest.dhr URI, and are then sent
|
||||
to a single legacyDhrDspIngestRoute URI for legacy processing and
|
||||
separate dxxIngestRoute URIs for Java processing (all handled below) -->
|
||||
<camelContext id="nonClusteredDhrDspRoutes"
|
||||
xmlns="http://camel.apache.org/schema/spring" errorHandlerRef="errorHandler">
|
||||
<!-- Begin non-clustered dhr Routes -->
|
||||
<route id="dhrIngestFilter">
|
||||
<!-- Begin non-clustered DHR/DSP Routes -->
|
||||
<route id="dhrDspIngestFilter">
|
||||
<from uri="jms-durable:queue:Ingest.dhr" />
|
||||
<setHeader headerName="pluginName">
|
||||
<constant>dhr</constant>
|
||||
|
@ -44,23 +54,39 @@
|
|||
</route>
|
||||
</camelContext>
|
||||
|
||||
<camelContext id="clusteredDHRroutes"
|
||||
<camelContext id="clusteredDhrDspRoutes"
|
||||
xmlns="http://camel.apache.org/schema/spring" errorHandlerRef="errorHandler">
|
||||
<!-- Begin legacy dhr/dsp Routes -->
|
||||
<route id="legacyDhrDspIngestRoute">
|
||||
<from uri="jms-durable:queue:legacyDhrDspProcess" />
|
||||
<doTry>
|
||||
<pipeline>
|
||||
<bean ref="serializationUtil" method="transformFromThrift" />
|
||||
<bean ref="dhrDecodeSrv" method="legacyProcess" />
|
||||
</pipeline>
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to uri="log:dhr?level=INFO" />
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
|
||||
<!-- Begin dhr Routes -->
|
||||
<route id="dhrIngestRoute">
|
||||
<from uri="jms-durable:queue:dhrProcess" />
|
||||
<doTry>
|
||||
<pipeline>
|
||||
<bean ref="serializationUtil" method="transformFromThrift" />
|
||||
<bean ref="dhrDecodeSrv" method="process" />
|
||||
<filter>
|
||||
<method ref="dhrGather" method="executeAllowed" />
|
||||
<bean ref="serializationUtil" method="transformFromThrift" />
|
||||
<filter>
|
||||
<method ref="dhrGather" method="precipExists" />
|
||||
<bean ref="dhrDecoder" method="execute" />
|
||||
<bean ref="dspDecoder" method="execute" />
|
||||
<!-- TODO: this will eventually continue the route to HPE Field
|
||||
Gen -->
|
||||
<method ref="dhrDecodeSrv" method="prepareForGather" />
|
||||
<filter>
|
||||
<method ref="dhrGather" method="precipExists" />
|
||||
<bean ref="dhrDecoder" method="execute" />
|
||||
<!-- TODO: this will eventually continue the route to HPE Field
|
||||
Gen -->
|
||||
</filter>
|
||||
</filter>
|
||||
</filter>
|
||||
</pipeline>
|
||||
|
@ -70,10 +96,35 @@
|
|||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
|
||||
<!-- Begin dsp Routes -->
|
||||
<route id="dspIngestRoute">
|
||||
<from uri="jms-durable:queue:dspProcess" />
|
||||
<doTry>
|
||||
<pipeline>
|
||||
<filter>
|
||||
<method ref="dspGather" method="executeAllowed" />
|
||||
<bean ref="serializationUtil" method="transformFromThrift" />
|
||||
<filter>
|
||||
<method ref="dhrDecodeSrv" method="prepareForGather" />
|
||||
<filter>
|
||||
<method ref="dspGather" method="precipExists" />
|
||||
<bean ref="dspDecoder" method="execute" />
|
||||
<!-- TODO: this will eventually continue the route to HPE Field
|
||||
Gen -->
|
||||
</filter>
|
||||
</filter>
|
||||
</filter>
|
||||
</pipeline>
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to uri="log:dsp?level=INFO" />
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
</camelContext>
|
||||
|
||||
<bean factory-bean="contextManager" factory-method="registerClusteredContext">
|
||||
<constructor-arg ref="clusteredDHRroutes" />
|
||||
<constructor-arg ref="clusteredDhrDspRoutes" />
|
||||
</bean>
|
||||
|
||||
</beans>
|
|
@ -25,6 +25,7 @@ import java.io.File;
|
|||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -44,6 +45,7 @@ import com.raytheon.uf.edex.core.EdexException;
|
|||
import com.raytheon.uf.edex.database.dao.CoreDao;
|
||||
import com.raytheon.uf.edex.database.dao.DaoConfig;
|
||||
import com.raytheon.uf.edex.ohd.MainMethod;
|
||||
import com.raytheon.uf.edex.plugin.mpe.gather.dhr.DHRGather;
|
||||
|
||||
/**
|
||||
* Service implementation for decoding DHR radar files.
|
||||
|
@ -67,6 +69,9 @@ import com.raytheon.uf.edex.ohd.MainMethod;
|
|||
* Jan 10, 2016 6058 bkowal Removed direct usage of the Java-based DHRGather.
|
||||
* Aug 02, 2017 6334 bkowal Write DHR/DSP gather files with the correct permissions.
|
||||
* Aug 07, 2017 6334 bkowal Directories are now created with 770 permissions and files 660.
|
||||
* Jul 19, 2018 5588 mapeters More fully separate legacy/java decode paths (e.g. use separate
|
||||
* gather dirs), use separate JMS uris for DHR/DSP in java path
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -104,7 +109,11 @@ public class HPEDhrSrv {
|
|||
|
||||
private static final int DT_IDX = 2;
|
||||
|
||||
private static final String JMS_QUEUE_URI = "jms-durable:queue:dhrProcess";
|
||||
private static final String DHR_JMS_QUEUE_URI = "jms-durable:queue:dhrProcess";
|
||||
|
||||
private static final String DSP_JMS_QUEUE_URI = "jms-durable:queue:dspProcess";
|
||||
|
||||
private static final String LEGACY_DHR_DSP_JMS_QUEUE_URI = "jms-durable:queue:legacyDhrDspProcess";
|
||||
|
||||
private final AppsDefaults appsDefaults = AppsDefaults.getInstance();
|
||||
|
||||
|
@ -127,27 +136,32 @@ public class HPEDhrSrv {
|
|||
public static final String KSH = "ksh";
|
||||
|
||||
/**
|
||||
* Route endpoint for "dhrIngestRoute". Takes a message, writes the file to
|
||||
* disk, and then runs the DHR data processing scripts so the file is
|
||||
* ingested.
|
||||
* Route endpoint for "legacyDhrDspIngestRoute". Takes a message, writes the
|
||||
* file to disk, and then runs the DHR data processing scripts so the file
|
||||
* is ingested. This is everything necessary for legacy processing of the
|
||||
* given message.
|
||||
*
|
||||
* @param message
|
||||
* A <code>HPEDhrMessage</code> describing the DHR radar file to
|
||||
* be ingested.
|
||||
*/
|
||||
public void process(HPEDhrMessage message) {
|
||||
try {
|
||||
writeFile(message);
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.handle(Priority.PROBLEM, "HPE cannot create output file.",
|
||||
e);
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
logger.handle(Priority.PROBLEM,
|
||||
"HPE Error writing updated contents of HPE file", e);
|
||||
return;
|
||||
public void legacyProcess(HPEDhrMessage message) {
|
||||
if (writeFile(message, true)) {
|
||||
runLegacyGatherScripts();
|
||||
}
|
||||
runGatherScripts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Route endpoint for "dhrIngestRoute" and "dspIngestRoute". Takes a message
|
||||
* and writes the file to disk so that it can be used by DHR/DSP Gather.
|
||||
*
|
||||
* @param message
|
||||
* A <code>HPEDhrMessage</code> describing the DHR radar file to
|
||||
* be ingested.
|
||||
* @return true if the file was successfully written, false otherwise
|
||||
*/
|
||||
public boolean prepareForGather(HPEDhrMessage message) {
|
||||
return writeFile(message, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,44 +174,55 @@ public class HPEDhrSrv {
|
|||
* @param message
|
||||
* A <code>HPEDhrMessage</code> describing the DHR radar file to
|
||||
* be ingested.
|
||||
* @throws FileNotFoundException
|
||||
* If the output file cannot be created or opened for any
|
||||
* reason.
|
||||
* @throws IOException
|
||||
* If an I/O error occurs while writing the file.
|
||||
* @param legacy
|
||||
* whether to write the file to the legacy product dir or the
|
||||
* Java-based product dir
|
||||
* @return true if the file was successfully written, false otherwise
|
||||
*/
|
||||
private void writeFile(HPEDhrMessage message)
|
||||
throws FileNotFoundException, IOException {
|
||||
private boolean writeFile(HPEDhrMessage message, boolean legacy) {
|
||||
String dtype = message.getDtype();
|
||||
String outname = dtype + message.getRadarId() + "." + message.getDt();
|
||||
|
||||
String dirToken = DHR.equals(dtype) ? DHR_PROD_DIR : DSP_PROD_DIR;
|
||||
String outPath;
|
||||
if (dtype.equals(DHR)) {
|
||||
outPath = appsDefaults.getToken(DHR_PROD_DIR);
|
||||
if (legacy) {
|
||||
outPath = appsDefaults.getToken(dirToken);
|
||||
} else {
|
||||
outPath = appsDefaults.getToken(DSP_PROD_DIR);
|
||||
}
|
||||
File oP = new File(outPath);
|
||||
if (!oP.exists()) {
|
||||
com.raytheon.uf.common.util.file.Files.createDirectories(
|
||||
oP.toPath(),
|
||||
FilePermissionConstants.POSIX_DIRECTORY_ATTRIBUTES);
|
||||
Path path = AppsDefaultsConversionWrapper
|
||||
.getPathForTokenWithoutCreating(dirToken);
|
||||
outPath = path.toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
byte[] fileContents = message.getData();
|
||||
int offset = findStartRadarData(new String(fileContents, 0, 80));
|
||||
String outFile = FileUtil.join(outPath, outname);
|
||||
try (OutputStream os = IOPermissionsHelper.getOutputStream(
|
||||
new File(outFile).toPath(),
|
||||
FilePermissionConstants.POSIX_FILE_SET);
|
||||
BufferedOutputStream bos = new BufferedOutputStream(os)) {
|
||||
bos.write(fileContents, offset, fileContents.length - offset);
|
||||
try {
|
||||
File oP = new File(outPath);
|
||||
if (!oP.exists()) {
|
||||
com.raytheon.uf.common.util.file.Files.createDirectories(
|
||||
oP.toPath(),
|
||||
FilePermissionConstants.POSIX_DIRECTORY_ATTRIBUTES);
|
||||
}
|
||||
|
||||
byte[] fileContents = message.getData();
|
||||
int offset = findStartRadarData(new String(fileContents, 0, 80));
|
||||
String outFile = FileUtil.join(outPath, outname);
|
||||
try (OutputStream os = IOPermissionsHelper.getOutputStream(
|
||||
new File(outFile).toPath(),
|
||||
FilePermissionConstants.POSIX_FILE_SET);
|
||||
BufferedOutputStream bos = new BufferedOutputStream(os)) {
|
||||
bos.write(fileContents, offset, fileContents.length - offset);
|
||||
}
|
||||
return true;
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.warn("HPE cannot create output file.", e);
|
||||
} catch (IOException e) {
|
||||
logger.warn("HPE Error writing updated contents of HPE file", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Route endpoint for "dhrIngestFilter". Reads the given file to memory and
|
||||
* determines whether or not this file is a DHR radar file. If it is, a
|
||||
* message is sent to a JMS queue so it is later ingested.
|
||||
* Route endpoint for "dhrDspIngestFilter". Reads the given file to memory
|
||||
* and determines whether or not this file is a DHR/DSP radar file. If it
|
||||
* is, a message is sent to a JMS queue so it is later ingested.
|
||||
*
|
||||
* @param fileContents
|
||||
* The radar file content
|
||||
|
@ -239,8 +264,11 @@ public class HPEDhrSrv {
|
|||
|
||||
/**
|
||||
* Takes the given parameters and constructs a <code>HPEDhrMessage</code> to
|
||||
* be placed onto the queue used by <code>HPEDhrSrv</code> for actual data
|
||||
* processing.
|
||||
* be placed onto the appropriate queues used by <code>HPEDhrSrv</code> for
|
||||
* actual data processing. If parallel exec is enabled, the file will be
|
||||
* placed both on the legacy DHR/DSP queue, and the product-type-specific
|
||||
* queue for Java processing. Otherwise, it will just be placed on the
|
||||
* legacy queue.
|
||||
*
|
||||
* @param data
|
||||
* The contents of the radar file.
|
||||
|
@ -261,13 +289,20 @@ public class HPEDhrSrv {
|
|||
String dt) throws SerializationException, EdexException {
|
||||
HPEDhrMessage message = new HPEDhrMessage(data, radid, dtype, dt);
|
||||
byte[] messageData = SerializationUtil.transformToThrift(message);
|
||||
EDEXUtil.getMessageProducer().sendAsyncUri(JMS_QUEUE_URI, messageData);
|
||||
EDEXUtil.getMessageProducer().sendAsyncUri(LEGACY_DHR_DSP_JMS_QUEUE_URI,
|
||||
messageData);
|
||||
if (AppsDefaultsConversionWrapper.parallelExecEnabled()) {
|
||||
String jmsQueueUri = DHR.equals(dtype) ? DHR_JMS_QUEUE_URI
|
||||
: DSP_JMS_QUEUE_URI;
|
||||
EDEXUtil.getMessageProducer().sendAsyncUri(jmsQueueUri,
|
||||
messageData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the DSPgather and DHRgather data processing scripts.
|
||||
*/
|
||||
private void runGatherScripts() {
|
||||
private void runLegacyGatherScripts() {
|
||||
int exitValue = MainMethod.runProgram(KSH,
|
||||
appsDefaults.getToken(PPROC_BIN) + File.separatorChar
|
||||
+ DSP_GATHER);
|
||||
|
|
|
@ -56,7 +56,6 @@ import com.raytheon.uf.edex.plugin.ffmp.FFMPGenerator;
|
|||
* 02/01/13 1569 D. Hladky Added constants
|
||||
* 02/25/13 1660 D. Hladky Moved FFTI processing to help with mosaic memory usage
|
||||
* 01/10/14 2359 njensen Fix exception logging
|
||||
* 03/07/17 DR 11861 lshi FFMP use of QPF in Basin Table
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -344,7 +343,7 @@ public class FFTI implements Runnable {
|
|||
if (values.getGuids() != null
|
||||
&& values.getQpes() != null) {
|
||||
tempVal = FFMPUtils.getMaxRatioValue(
|
||||
values.getQpes(), null, values.getGuids());
|
||||
values.getQpes(), values.getGuids());
|
||||
}
|
||||
} else if (attribute.getAttributeName().equals(
|
||||
FFTIAttributeXML.ATTRIBUTE.DIFF.getAttribute())) {
|
||||
|
@ -352,7 +351,7 @@ public class FFTI implements Runnable {
|
|||
if (values.getGuids() != null
|
||||
&& values.getQpes() != null) {
|
||||
tempVal = FFMPUtils.getMaxDiffValue(
|
||||
values.getQpes(), null, values.getGuids());
|
||||
values.getQpes(), values.getGuids());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,7 +401,7 @@ public class FFTI implements Runnable {
|
|||
|
||||
if (values.getGuids() != null
|
||||
&& values.getQpes() != null) {
|
||||
val = FFMPUtils.getMaxRatioValue(values.getQpes(), null,
|
||||
val = FFMPUtils.getMaxRatioValue(values.getQpes(),
|
||||
values.getGuids());
|
||||
}
|
||||
|
||||
|
@ -411,7 +410,7 @@ public class FFTI implements Runnable {
|
|||
|
||||
if (values.getGuids() != null
|
||||
&& values.getQpes() != null) {
|
||||
val = FFMPUtils.getMaxDiffValue(values.getQpes(), null,
|
||||
val = FFMPUtils.getMaxDiffValue(values.getQpes(),
|
||||
values.getGuids());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.edex.plugin.mpe.gather;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import com.raytheon.uf.edex.plugin.mpe.gather.radar.InvalidMpeRadarException;
|
||||
import com.raytheon.uf.edex.plugin.mpe.gather.radar.MpeRadarSymbologyData;
|
||||
|
||||
/**
|
||||
* Extension of {@link MpeRadarSymbologyData} designed to only read the Radar
|
||||
* Symbology data from an input file. Also handles the case when the Radar
|
||||
* Symbology data cannot be found in the specified file.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 10, 2017 6058 bkowal Initial creation
|
||||
* Jul 24, 2018 5588 mapeters Moved from com.raytheon.uf.edex.plugin.mpe.gather.dhr
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bkowal
|
||||
*/
|
||||
|
||||
public final class MpePrecipCheckRadarSymbologyData
|
||||
extends MpeRadarSymbologyData {
|
||||
|
||||
public boolean readPrecipIndicationParams(final ByteBuffer buf) {
|
||||
try {
|
||||
readPsmParams(buf);
|
||||
} catch (InvalidMpeRadarException e) {
|
||||
/*
|
||||
* Apparently, there is a mixture of files with the proper structure
|
||||
* and files without the proper structure in the DHR/DSP Gather file
|
||||
* directories. So, if a file with the wrong structure is
|
||||
* encountered, it will just be ignored to match the legacy
|
||||
* implementation.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
return (getPsmParams() != null
|
||||
&& getPsmParams().length > MpeRadarGatherConstants.DHR_PARAM_PRECIP);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,346 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.edex.plugin.mpe.gather;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.shef.tables.Radarloc;
|
||||
import com.raytheon.uf.common.mpe.util.AppsDefaultsConversionWrapper;
|
||||
import com.raytheon.uf.common.time.util.ITimer;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.edex.database.cluster.ClusterLockUtils;
|
||||
import com.raytheon.uf.edex.database.cluster.ClusterTask;
|
||||
import com.raytheon.uf.edex.plugin.mpe.dao.impl.RadarlocDao;
|
||||
|
||||
/**
|
||||
* Replacement for the DHRgather and DSPgather scripts. Those scripts do not
|
||||
* perform any file copying or moving (all commands that originally handled it
|
||||
* have previously been commented out in the scripts). HPEDhrSrv already handles
|
||||
* writing and/or moving the radar products it supports.
|
||||
*
|
||||
* This script has been setup to scan the DHR or DSP product directory for new
|
||||
* files that have been added since its last run. The parameters will be checked
|
||||
* in each file that is scanned to determine if the file includes precipitation
|
||||
* data.
|
||||
*
|
||||
* Any time a DHR product that included precipitation was found by the legacy
|
||||
* script, it would start and manage and monitor an external process for
|
||||
* decoding of both DHR and DSP files. This external process would be allowed to
|
||||
* run for a maximum of 20 minutes unless additional precipitation data was
|
||||
* discovered. This caused DHR/DSP products to be decoded within that 20-minute
|
||||
* window regardless of whether or not they had precipitation. However, this was
|
||||
* done only for stability reasons (so that the decoding process wasn't
|
||||
* starting/stopping continuously), as radar products without precipitation
|
||||
* don't actually need to be decoded. Thus, this is not needed now that the
|
||||
* process is on a camel route, so the 20-minute window and decoding products
|
||||
* without precipitation have been removed in this implementation.
|
||||
*
|
||||
* Also, in the legacy implementation, only DHR products were checked for
|
||||
* precipitation in order to determine when decoding of both DHR and DSP files
|
||||
* should occur. With this new implementation, they are each checked separately
|
||||
* to avoid timing issues and ensure that radar products with precipitation are
|
||||
* correctly decoded.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 24, 2018 5588 mapeters Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mapeters
|
||||
*/
|
||||
public abstract class MpeRadarGather {
|
||||
|
||||
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
protected final String productType;
|
||||
|
||||
protected final String gatherDirToken;
|
||||
|
||||
protected final String clusterLockName;
|
||||
|
||||
protected final String clusterLockDetails;
|
||||
|
||||
protected MpeRadarGather(String productType, String gatherDir) {
|
||||
this.productType = productType;
|
||||
this.gatherDirToken = gatherDir;
|
||||
this.clusterLockName = productType
|
||||
+ MpeRadarGatherConstants.CLUSTER_LOCK_NAME_SUFFIX;
|
||||
this.clusterLockDetails = productType
|
||||
+ MpeRadarGatherConstants.CLUSTER_LOCK_DETAILS_SUFFIX;
|
||||
}
|
||||
|
||||
public boolean precipExists() {
|
||||
final Date currentRunDate = TimeUtil.newDate();
|
||||
ITimer timer = TimeUtil.getTimer();
|
||||
timer.start();
|
||||
|
||||
boolean precipFound = false;
|
||||
logger.info("{} Gather has started ...", productType);
|
||||
if (shouldExecute()) {
|
||||
try {
|
||||
precipFound = gather(currentRunDate);
|
||||
} catch (Exception e) {
|
||||
logger.warn(productType + " Gather failed.", e);
|
||||
}
|
||||
}
|
||||
timer.stop();
|
||||
logger.info("{} Gather has successfully finished in {}.", productType,
|
||||
TimeUtil.prettyDuration(timer.getElapsedTime()));
|
||||
return precipFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the Java version of MPE Radar Gather should be allowed to
|
||||
* run/execute; dependent on whether or not parallel execution mode has been
|
||||
* enabled.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean executeAllowed() {
|
||||
return AppsDefaultsConversionWrapper.parallelExecEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* MPE Radar Gather should only be executed when there is one or more radar
|
||||
* in use. This method will determine if there is a sufficient number of
|
||||
* radars in use.
|
||||
*
|
||||
* @return {@code true}, if there are a sufficient number of radars in use.
|
||||
* {@code false}, otherwise.
|
||||
*/
|
||||
private boolean shouldExecute() {
|
||||
final List<Radarloc> radarsInUse = new RadarlocDao()
|
||||
.getInUseRadarlocs();
|
||||
if (radarsInUse.isEmpty()) {
|
||||
logger.info("No radars are in use. Halting {} Gather.",
|
||||
productType);
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.info("Found {} radars in use. {} Gather continuing ...",
|
||||
radarsInUse.size(), productType);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean gather(final Date currentRunDate) throws Exception {
|
||||
/*
|
||||
* Get the location of the Product Directory from Apps_Defaults.
|
||||
*/
|
||||
Path productDir = AppsDefaultsConversionWrapper
|
||||
.getPathForTokenWithoutCreating(gatherDirToken);
|
||||
if (!Files.exists(productDir)) {
|
||||
/*
|
||||
* If the directory does not exist, there are no products to
|
||||
* process.
|
||||
*/
|
||||
logger.info(
|
||||
"The {} Product directory: {} does not exist. Halting {} Gather.",
|
||||
productType, productDir, productType);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The legacy DHRgather script used to place an empty file on the
|
||||
* filesystem to determine when it last ran. The new version will use
|
||||
* cluster locks.
|
||||
*/
|
||||
final ClusterTask clusterTask = ClusterLockUtils
|
||||
.lookupLock(clusterLockName, clusterLockDetails);
|
||||
Date lastRunDate = null;
|
||||
if (clusterTask != null && clusterTask.getExtraInfo() != null) {
|
||||
try {
|
||||
lastRunDate = MpeRadarGatherConstants.lockDF.get()
|
||||
.parse(clusterTask.getExtraInfo());
|
||||
} catch (ParseException e) {
|
||||
logger.error(
|
||||
"Failed to parse the date: " + lastRunDate
|
||||
+ "associated with the Cluster Lock. Resetting last run date.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastRunDate == null) {
|
||||
/*
|
||||
* No previous record of when this Gather was last ran or this is
|
||||
* the first time that Gather is running.
|
||||
*/
|
||||
storeCurrentRunDate(currentRunDate, false);
|
||||
logger.info(
|
||||
"First run of {} Gather. Successfully prepared for subsequent runs. Halting {} Gather.",
|
||||
productType, productType);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Identify all product files that are newer than the last run date.
|
||||
*/
|
||||
final long lastRunDateMillis = lastRunDate.getTime();
|
||||
final Set<Path> gatherFilesSet = new HashSet<>();
|
||||
Files.walkFileTree(productDir, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path path,
|
||||
BasicFileAttributes attrs) throws IOException {
|
||||
final long modifiedTime = Files.getLastModifiedTime(path)
|
||||
.toMillis();
|
||||
if (modifiedTime >= lastRunDateMillis
|
||||
&& modifiedTime < currentRunDate.getTime()) {
|
||||
gatherFilesSet.add(path);
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
|
||||
if (gatherFilesSet.isEmpty()) {
|
||||
logger.info(
|
||||
"No {} products created on or after {} were found in the {} Product directory: {}. Halting {} Gather.",
|
||||
productType, lastRunDate.toString(), productType,
|
||||
productDir.toString(), productType);
|
||||
storeCurrentRunDate(currentRunDate, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if the start_hpe script should be started. TODO: this
|
||||
* version of DHR/DSP Gather will not actually interact with the
|
||||
* successor of start_hpe until it has been implemented in Java.
|
||||
*/
|
||||
boolean precipFound = false;
|
||||
for (Path gatherFilePath : gatherFilesSet) {
|
||||
try {
|
||||
logger.info("Evaluating {} product: {} ...", productType,
|
||||
gatherFilePath.toString());
|
||||
MpePrecipCheckRadarSymbologyData radarSymData = new MpePrecipCheckRadarSymbologyData();
|
||||
File f = gatherFilePath.toFile();
|
||||
|
||||
boolean hasPrecipParams;
|
||||
try (FileInputStream fis = new FileInputStream(f);
|
||||
FileChannel fc = fis.getChannel()) {
|
||||
ByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0,
|
||||
f.length());
|
||||
hasPrecipParams = radarSymData
|
||||
.readPrecipIndicationParams(byteBuffer);
|
||||
}
|
||||
|
||||
if (!hasPrecipParams) {
|
||||
/*
|
||||
* The precipitation information was not present in the file
|
||||
* that was checked. Remove this file.
|
||||
*/
|
||||
logger.info(
|
||||
"Precipitation information not included in {} product: {}.",
|
||||
productType, gatherFilePath);
|
||||
deletePath(gatherFilePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
final float param = radarSymData
|
||||
.getPsmParams()[MpeRadarGatherConstants.DHR_PARAM_PRECIP];
|
||||
/*
|
||||
* This if/else statement used to be reversed based on the if
|
||||
* statement in: get_dhrpsm/TEXT/main_DHRPsm.c starting on line
|
||||
* 115, which made it appear that a param value > 0 indicated no
|
||||
* precipitation and a value <= 0 indicated precipitation.
|
||||
*
|
||||
* However, DHRgather actually uses the PSM value printed in
|
||||
* that C function (line 113) and not its return value, so a
|
||||
* param value > 0 actually indicates precipitation.
|
||||
*/
|
||||
if (param > 0.0) {
|
||||
logger.info("Precipitation was detected in {} product: {}.",
|
||||
productType, gatherFilePath);
|
||||
precipFound = true;
|
||||
} else {
|
||||
logger.info(
|
||||
"Precipitation was NOT detected in {} product: {}.",
|
||||
productType, gatherFilePath);
|
||||
deletePath(gatherFilePath);
|
||||
}
|
||||
logger.info("{} product: {} evaluation complete.", productType,
|
||||
gatherFilePath.toString());
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to load " + productType
|
||||
+ " Radar product: " + gatherFilePath.toString()
|
||||
+ ". Skipping file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the gather directory if no precipitation was found
|
||||
if (!precipFound) {
|
||||
logger.info(
|
||||
"Removing all {} products in {} due to no precipitation.",
|
||||
productType, productDir);
|
||||
for (File file : productDir.toFile().listFiles()) {
|
||||
if (!file.isFile()) {
|
||||
// Skip non-files
|
||||
continue;
|
||||
}
|
||||
deletePath(file.toPath());
|
||||
}
|
||||
}
|
||||
|
||||
storeCurrentRunDate(currentRunDate, true);
|
||||
return precipFound;
|
||||
}
|
||||
|
||||
private void deletePath(Path path) {
|
||||
try {
|
||||
Files.delete(path);
|
||||
} catch (IOException e) {
|
||||
logger.warn("Failed to delete " + productType + " product: " + path,
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeCurrentRunDate(final Date currentRunDate,
|
||||
final boolean update) {
|
||||
final String extraInfo = MpeRadarGatherConstants.lockDF.get()
|
||||
.format(currentRunDate);
|
||||
if (update) {
|
||||
ClusterLockUtils.updateExtraInfo(clusterLockName,
|
||||
clusterLockDetails, extraInfo);
|
||||
} else {
|
||||
ClusterLockUtils.lock(clusterLockName, clusterLockDetails,
|
||||
extraInfo, 30, true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.edex.plugin.mpe.gather;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
/**
|
||||
* Common, centralized declaration of constants that will be utilized by
|
||||
* {@link MpeRadarGather}s.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 30, 2016 4625 bkowal Initial creation
|
||||
* Jul 24, 2018 5588 mapeters Added some constants for addition of DSPGather, refactored from
|
||||
* com.raytheon.uf.edex.plugin.mpe.gather.dhr.DHRGatherConstants
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bkowal
|
||||
*/
|
||||
|
||||
public class MpeRadarGatherConstants {
|
||||
|
||||
private static final String LOCK_DATE_FORMAT = "MM-dd-yyy HH:mm";
|
||||
|
||||
public static final ThreadLocal<SimpleDateFormat> lockDF = new ThreadLocal<SimpleDateFormat>() {
|
||||
@Override
|
||||
protected SimpleDateFormat initialValue() {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(LOCK_DATE_FORMAT);
|
||||
return sdf;
|
||||
}
|
||||
};
|
||||
|
||||
public static final String CLUSTER_LOCK_NAME_SUFFIX = "GatherLock";
|
||||
|
||||
public static final String CLUSTER_LOCK_DETAILS_SUFFIX = "Gather";
|
||||
|
||||
public static final String DHR_PRODUCT_TYPE = "DHR";
|
||||
|
||||
public static final String DSP_PRODUCT_TYPE = "DSP";
|
||||
|
||||
public static final int DHR_DEFAULT_VERSION = 8;
|
||||
|
||||
public static final int DHR_PARAM_PRECIP = 4;
|
||||
|
||||
public static class AppsDefaults {
|
||||
|
||||
public static final String DHR_PROD_DIR = "dhr_prod_dir";
|
||||
|
||||
public static final String DSP_PROD_DIR = "dsp_prod_dir";
|
||||
}
|
||||
|
||||
private MpeRadarGatherConstants() {
|
||||
}
|
||||
}
|
|
@ -19,52 +19,11 @@
|
|||
**/
|
||||
package com.raytheon.uf.edex.plugin.mpe.gather.dhr;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.common.dataplugin.shef.tables.Radarloc;
|
||||
import com.raytheon.uf.common.mpe.util.AppsDefaultsConversionWrapper;
|
||||
import com.raytheon.uf.common.ohd.AppsDefaults;
|
||||
import com.raytheon.uf.common.time.util.ITimer;
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.edex.database.cluster.ClusterLockUtils;
|
||||
import com.raytheon.uf.edex.database.cluster.ClusterTask;
|
||||
import com.raytheon.uf.edex.plugin.mpe.dao.impl.RadarlocDao;
|
||||
import com.raytheon.uf.edex.plugin.mpe.gather.MpeRadarGather;
|
||||
import com.raytheon.uf.edex.plugin.mpe.gather.MpeRadarGatherConstants;
|
||||
|
||||
/**
|
||||
* Replacement for the DHRgather script. The DHRgather script does not perform
|
||||
* any file copying or moving (all commands that originally handled it have
|
||||
* previously been commented out in the script). {@link HPEDhrSrv} already
|
||||
* handles writing and/or moving the radar products it supports.
|
||||
*
|
||||
* This script has been setup to scan the DHR product directory for new files
|
||||
* that have been added since its last run. The parameters will be checked in
|
||||
* each file that is scanned to determine if the file includes precipitation
|
||||
* data.
|
||||
*
|
||||
* Any time a radar product that included precipitation was found by the legacy
|
||||
* script, it would start and manage and monitor an external process. This
|
||||
* external process would be allowed to run for a maximum of 20 minutes unless
|
||||
* additional precipitation data was discovered. That implementation will remain
|
||||
* as part of the legacy implementation.
|
||||
* Replacement for the DHRgather script.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -76,220 +35,18 @@ import com.raytheon.uf.edex.plugin.mpe.dao.impl.RadarlocDao;
|
|||
* Nov 22, 2016 5588 nabowle Check PSM param for precipitation.
|
||||
* Jan 10, 2016 6058 bkowal Silently ignore invalid DHR input files. Do not fully
|
||||
* read an entire file just to check for precip.
|
||||
* Jul 24, 2018 5588 mapeters Fix determination of whether DHR product has precip,
|
||||
* account for legacy/java decode paths using separate
|
||||
* gather dirs, abstracted out to {@link MpeRadarGather}
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bkowal
|
||||
*/
|
||||
public class DHRGather extends MpeRadarGather {
|
||||
|
||||
public class DHRGather {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public boolean precipExists() {
|
||||
final Date currentRunDate = TimeUtil.newDate();
|
||||
ITimer timer = TimeUtil.getTimer();
|
||||
timer.start();
|
||||
|
||||
boolean precipFound = false;
|
||||
logger.info("DHRGather has started ...");
|
||||
if (shouldExecute()) {
|
||||
try {
|
||||
precipFound = gather(currentRunDate);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Gather failed. ", e);
|
||||
}
|
||||
}
|
||||
timer.stop();
|
||||
logger.info("DHRGather has successfully finished in {}.",
|
||||
TimeUtil.prettyDuration(timer.getElapsedTime()));
|
||||
return precipFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the Java version of DHR Gather should be allowed to
|
||||
* run/execute; dependent on whether or not parallel execution mode has been
|
||||
* enabled.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean executeAllowed() {
|
||||
return AppsDefaultsConversionWrapper.parallelExecEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link DHRGather} should only be executed when there is one or more radar
|
||||
* in use. This method will determine if there is a sufficient number of
|
||||
* radars in use.
|
||||
*
|
||||
* @return {@code true}, if there are a sufficient number of radars in use.
|
||||
* {@code false}, otherwise.
|
||||
*/
|
||||
private boolean shouldExecute() {
|
||||
final List<Radarloc> radarsInUse = new RadarlocDao()
|
||||
.getInUseRadarlocs();
|
||||
if (radarsInUse.isEmpty()) {
|
||||
logger.info("No radars are in use. Halting DHR Gather.");
|
||||
return false;
|
||||
}
|
||||
|
||||
logger.info("Found {} radars in use. DHR Gather continuing ...",
|
||||
radarsInUse.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean gather(final Date currentRunDate) throws Exception {
|
||||
/*
|
||||
* Get the location of the DHR Product Directory from Apps_Defaults.
|
||||
*/
|
||||
final String dhrProdDir = AppsDefaults.getInstance()
|
||||
.getToken(DHRGatherConstants.AppsDefaults.DHR_PROD_DIR, null);
|
||||
if (dhrProdDir == null) {
|
||||
throw new DHRGatherFailedException(
|
||||
"Failed to retrieve the DHR Product directory from "
|
||||
+ AppsDefaults.NAME + ". Please verify that the '"
|
||||
+ DHRGatherConstants.AppsDefaults.DHR_PROD_DIR
|
||||
+ "' property has been defined.");
|
||||
}
|
||||
|
||||
Path dhrProductPath = Paths.get(dhrProdDir);
|
||||
if (!Files.exists(dhrProductPath)) {
|
||||
/*
|
||||
* If the directory does not exist, there are not any dhr products
|
||||
* to process.
|
||||
*/
|
||||
logger.info(
|
||||
"The DHR Product directory: {} does not exist. Halting DHR Gather.",
|
||||
dhrProductPath.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The legacy DHRgather script used to place an empty file on the
|
||||
* filesystem to determine when it last ran. The new version will use
|
||||
* cluster locks.
|
||||
*/
|
||||
final ClusterTask clusterTask = ClusterLockUtils.lookupLock(
|
||||
DHRGatherConstants.CLUSTER_LOCK_NAME,
|
||||
DHRGatherConstants.CLUSTER_LOCK_DETAILS);
|
||||
Date lastRunDate = null;
|
||||
if (clusterTask != null && clusterTask.getExtraInfo() != null) {
|
||||
try {
|
||||
lastRunDate = DHRGatherConstants.lockDF.get()
|
||||
.parse(clusterTask.getExtraInfo());
|
||||
} catch (ParseException e) {
|
||||
logger.error(
|
||||
"Failed to parse the date: " + lastRunDate
|
||||
+ "associated with the Cluster Lock. Resetting last run date.",
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastRunDate == null) {
|
||||
/*
|
||||
* No previous record of when DHRGather was last ran or this is the
|
||||
* first time that DHRGather is running.
|
||||
*/
|
||||
storeCurrentRunDate(currentRunDate, false);
|
||||
logger.info(
|
||||
"First run of DHR Gather. Successfully prepared for subsequent runs. Halting DHR Gather.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Identify all DHR product files that are newer than the last run date.
|
||||
*/
|
||||
final long lastRunDateMillis = lastRunDate.getTime();
|
||||
final Set<Path> gatherFilesSet = new HashSet<>();
|
||||
Files.walkFileTree(dhrProductPath, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path path,
|
||||
BasicFileAttributes attrs) throws IOException {
|
||||
final long modifiedTime = Files.getLastModifiedTime(path)
|
||||
.toMillis();
|
||||
if (modifiedTime >= lastRunDateMillis
|
||||
&& modifiedTime < currentRunDate.getTime()) {
|
||||
gatherFilesSet.add(path);
|
||||
}
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
|
||||
if (gatherFilesSet.isEmpty()) {
|
||||
logger.info(
|
||||
"No DHR products created on or after {} were found in the DHR Product directory: {}. Halting DHR Gather.",
|
||||
lastRunDate.toString(), dhrProductPath.toString());
|
||||
storeCurrentRunDate(currentRunDate, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if the start_hpe script should be started. TODO: this
|
||||
* version of DHR Gather will not actually interact with the successor
|
||||
* of start_hpe until it has been implemented in Java.
|
||||
*/
|
||||
boolean precipFound = false;
|
||||
for (Path gatherFilePath : gatherFilesSet) {
|
||||
try {
|
||||
logger.info("Evaluating DHR product: {} ...",
|
||||
gatherFilePath.toString());
|
||||
MpePrecipCheckRadarSymbologyData radarSymData = new MpePrecipCheckRadarSymbologyData();
|
||||
File f = gatherFilePath.toFile();
|
||||
try (FileInputStream fis = new FileInputStream(f);
|
||||
FileChannel fc = fis.getChannel()) {
|
||||
ByteBuffer byteBuffer = fc.map(MapMode.READ_ONLY, 0,
|
||||
f.length());
|
||||
if (!radarSymData.readPrecipIndicationParams(byteBuffer)) {
|
||||
/*
|
||||
* The precipitation information was not present in the
|
||||
* file that was checked. Silently skip this file.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
final float param = radarSymData
|
||||
.getPsmParams()[DHRGatherConstants.DHR_PARAM_PRECIP];
|
||||
/*
|
||||
* This if statement is based on the if statement in:
|
||||
* get_dhrpsm/TEXT/main_DHRPsm.c starting on line 115. A param
|
||||
* value > 0 indicated no precipitation and a value <= 0
|
||||
* indicated precipitation.
|
||||
*/
|
||||
if (param > 0.0) {
|
||||
logger.info(
|
||||
"Precipitation was NOT detected in DHR product: {}.",
|
||||
gatherFilePath.toString());
|
||||
} else {
|
||||
logger.info(
|
||||
"Precipitation was detected in DHR product: {}.",
|
||||
gatherFilePath.toString());
|
||||
precipFound = true;
|
||||
break;
|
||||
}
|
||||
logger.info("DHR product: {} evaluation complete.",
|
||||
gatherFilePath.toString());
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to load DHR Radar product: "
|
||||
+ gatherFilePath.toString() + ". Skipping file.", e);
|
||||
}
|
||||
}
|
||||
storeCurrentRunDate(currentRunDate, true);
|
||||
return precipFound;
|
||||
}
|
||||
|
||||
private void storeCurrentRunDate(final Date currentRunDate,
|
||||
final boolean update) {
|
||||
final String extraInfo = DHRGatherConstants.lockDF.get()
|
||||
.format(currentRunDate);
|
||||
if (update) {
|
||||
ClusterLockUtils.updateExtraInfo(
|
||||
DHRGatherConstants.CLUSTER_LOCK_NAME,
|
||||
DHRGatherConstants.CLUSTER_LOCK_DETAILS, extraInfo);
|
||||
} else {
|
||||
ClusterLockUtils.lock(DHRGatherConstants.CLUSTER_LOCK_NAME,
|
||||
DHRGatherConstants.CLUSTER_LOCK_DETAILS, extraInfo, 30,
|
||||
true);
|
||||
}
|
||||
public DHRGather() {
|
||||
super(MpeRadarGatherConstants.DHR_PRODUCT_TYPE,
|
||||
MpeRadarGatherConstants.AppsDefaults.DHR_PROD_DIR);
|
||||
}
|
||||
}
|
|
@ -48,6 +48,8 @@ import com.raytheon.uf.edex.plugin.mpe.gather.radar.MpeRadarInputException;
|
|||
* Nov 22, 2016 5588 nabowle Initial creation
|
||||
* Dec 14, 2016 5588 nabowle Fix negative values. Round to 3 decimals
|
||||
* to match legacy.
|
||||
* Jul 19, 2018 5588 mapeters Change rounding to truncating to match
|
||||
* legacy
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -56,7 +58,11 @@ import com.raytheon.uf.edex.plugin.mpe.gather.radar.MpeRadarInputException;
|
|||
|
||||
public class DSPDecoder extends MpeRadarDecoder<DSPRadarFile> {
|
||||
|
||||
private static final float ROUND_FACTOR = 1000F;
|
||||
/**
|
||||
* The factor that determines the number of decimal places to truncate the
|
||||
* data values to (1000 = 3 decimal places).
|
||||
*/
|
||||
private static final float TRUNCATE_FACTOR = 1000F;
|
||||
|
||||
private DspradarDao radarDao = new DspradarDao();
|
||||
|
||||
|
@ -120,14 +126,14 @@ public class DSPDecoder extends MpeRadarDecoder<DSPRadarFile> {
|
|||
|
||||
for (int j = 0; j < MpeRadarDecodeConstants.MAX_JHRAP; j++) {
|
||||
for (int i = 0; i < MpeRadarDecodeConstants.MAX_IHRAP; i++) {
|
||||
ledos.writeFloat(roundFloat(data[j][i]));
|
||||
ledos.writeFloat(truncateFloat(data[j][i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float roundFloat(float f) {
|
||||
return Math.round(f * ROUND_FACTOR) / ROUND_FACTOR;
|
||||
private float truncateFloat(float f) {
|
||||
return (int) (f * TRUNCATE_FACTOR) / TRUNCATE_FACTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.edex.plugin.mpe.gather.dsp;
|
||||
|
||||
import com.raytheon.uf.edex.plugin.mpe.gather.MpeRadarGather;
|
||||
import com.raytheon.uf.edex.plugin.mpe.gather.MpeRadarGatherConstants;
|
||||
|
||||
/**
|
||||
* Replacement for the DSPgather script.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 24, 2018 5588 mapeters Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mapeters
|
||||
*/
|
||||
public class DSPGather extends MpeRadarGather {
|
||||
|
||||
protected DSPGather() {
|
||||
super(MpeRadarGatherConstants.DSP_PRODUCT_TYPE,
|
||||
MpeRadarGatherConstants.AppsDefaults.DSP_PROD_DIR);
|
||||
}
|
||||
}
|
|
@ -36,6 +36,7 @@ import com.raytheon.uf.edex.plugin.mpe.gather.radar.MpeRadarProductDescription;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 22, 2016 5588 nabowle Initial creation
|
||||
* Jul 19, 2018 5588 mapeters Fix parsing of maxPrecipValue
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -44,8 +45,6 @@ import com.raytheon.uf.edex.plugin.mpe.gather.radar.MpeRadarProductDescription;
|
|||
|
||||
public class DSPProductDescription extends MpeRadarProductDescription {
|
||||
|
||||
private static final float PRECIP_DIVIDEND = 10.0f;
|
||||
|
||||
private static final class DSPDescriptionIndices {
|
||||
|
||||
public static final int START_DATE_INDEX = 17;
|
||||
|
@ -56,7 +55,7 @@ public class DSPProductDescription extends MpeRadarProductDescription {
|
|||
|
||||
public static final int DATA_LVL_SCALE_INDEX = 22;
|
||||
|
||||
public static final int MAX_PRECIP_INDEX = 21;
|
||||
public static final int MAX_PRECIP_INDEX = 37;
|
||||
}
|
||||
|
||||
private Calendar startDateTime;
|
||||
|
@ -71,7 +70,8 @@ public class DSPProductDescription extends MpeRadarProductDescription {
|
|||
|
||||
private short julianBeginTime;
|
||||
|
||||
public DSPProductDescription(ByteBuffer buf) throws InvalidMpeRadarException {
|
||||
public DSPProductDescription(ByteBuffer buf)
|
||||
throws InvalidMpeRadarException {
|
||||
super(buf);
|
||||
}
|
||||
|
||||
|
@ -84,8 +84,7 @@ public class DSPProductDescription extends MpeRadarProductDescription {
|
|||
(short) (julianBeginTime / TimeUtil.SECONDS_PER_MINUTE));
|
||||
minDataLevel = data[DSPDescriptionIndices.MIN_DATA_LVL_INDEX];
|
||||
dataLevelScaleFactor = data[DSPDescriptionIndices.DATA_LVL_SCALE_INDEX];
|
||||
maxPrecipValue = data[DSPDescriptionIndices.MAX_PRECIP_INDEX]
|
||||
/ PRECIP_DIVIDEND;
|
||||
maxPrecipValue = data[DSPDescriptionIndices.MAX_PRECIP_INDEX];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -41,6 +41,7 @@ import com.raytheon.uf.edex.plugin.mpe.gather.radar.MpeRadarSymbologyData;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 22, 2016 5588 nabowle Initial creation
|
||||
* Jul 24, 2018 5588 mapeters Use MpeRadarFile.BUILD_VERSION_5 constant
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -122,7 +123,7 @@ public class DSPRadarFile extends MpeRadarFile<DSPProductDescription> {
|
|||
adapt.setMaxZrefl(params[i++]);
|
||||
adapt.setMinBirng(params[i++]);
|
||||
|
||||
if (getVersion() == 5) {
|
||||
if (getVersion() == MpeRadarFile.BUILD_VERSION_5) {
|
||||
adapt.setMaxStmspd(params[i++]);
|
||||
adapt.setMaxTimdif(params[i++]);
|
||||
adapt.setMinArtcon(params[i++]);
|
||||
|
|
|
@ -22,7 +22,7 @@ package com.raytheon.uf.edex.plugin.mpe.gather.radar;
|
|||
import java.text.SimpleDateFormat;
|
||||
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.edex.plugin.mpe.gather.dhr.DHRGatherConstants;
|
||||
import com.raytheon.uf.edex.plugin.mpe.gather.MpeRadarGatherConstants;
|
||||
|
||||
/**
|
||||
* Constants for decoding DHR and DSP files. Based on
|
||||
|
@ -35,6 +35,7 @@ import com.raytheon.uf.edex.plugin.mpe.gather.dhr.DHRGatherConstants;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 22, 2016 5588 nabowle Initial creation
|
||||
* Jul 18, 2018 5588 mapeters Fix DSP dir constants
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -44,13 +45,13 @@ import com.raytheon.uf.edex.plugin.mpe.gather.dhr.DHRGatherConstants;
|
|||
public class MpeRadarDecodeConstants {
|
||||
|
||||
public static class AppsDefaults {
|
||||
public static final String DSP_GRID_DIR = "dhr_grid_dir";
|
||||
public static final String DSP_GRID_DIR = "dsp_grid_dir";
|
||||
|
||||
public static final String DSP_PROD_DIR = "dhr_prod_dir";
|
||||
public static final String DSP_PROD_DIR = "dsp_prod_dir";
|
||||
|
||||
public static final String DHR_GRID_DIR = "dhr_grid_dir";
|
||||
|
||||
public static final String DHR_PROD_DIR = DHRGatherConstants.AppsDefaults.DHR_PROD_DIR;
|
||||
public static final String DHR_PROD_DIR = MpeRadarGatherConstants.AppsDefaults.DHR_PROD_DIR;
|
||||
}
|
||||
|
||||
public static final ThreadLocal<SimpleDateFormat> filenameDateFormat = TimeUtil
|
||||
|
@ -129,7 +130,7 @@ public class MpeRadarDecodeConstants {
|
|||
|
||||
public static final int SHORT_BYTES = 2;
|
||||
|
||||
public static final int DEFAULT_BUILD_VERSION = DHRGatherConstants.DHR_DEFAULT_VERSION;
|
||||
public static final int DEFAULT_BUILD_VERSION = MpeRadarGatherConstants.DHR_DEFAULT_VERSION;
|
||||
|
||||
private MpeRadarDecodeConstants() {
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 22, 2016 5588 nabowle Initial creation
|
||||
* Dec 14, 2015 5588 nabowle Fix caching.
|
||||
* Jul 19, 2018 5588 mapeters Reverse lat/lon in Coordinates so
|
||||
* lon=x and lat=y
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -81,7 +83,7 @@ public class MpeRadarDecodeUtils {
|
|||
public static void buildLookupTable(int radLat, int radLon,
|
||||
int[][] quarterHrapToRadarAzimuth,
|
||||
int[][] quarterHrapToRadarRange) {
|
||||
Coordinate coord = new Coordinate(radLat, radLon);
|
||||
Coordinate coord = new Coordinate(radLon, radLat);
|
||||
SoftReference<int[][][]> cachedRef = lookupCache.get(coord);
|
||||
if (cachedRef != null) {
|
||||
int[][][] cachedTable = cachedRef.get();
|
||||
|
|
|
@ -25,8 +25,6 @@ import java.io.InputStream;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -36,7 +34,6 @@ import com.raytheon.uf.common.localization.PathManagerFactory;
|
|||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
||||
import com.raytheon.uf.common.mpe.util.AppsDefaultsConversionWrapper;
|
||||
import com.raytheon.uf.common.mpe.util.AppsDefaultsPathException;
|
||||
import com.raytheon.uf.common.ohd.AppsDefaults;
|
||||
import com.raytheon.uf.common.serialization.SerializationException;
|
||||
import com.raytheon.uf.common.serialization.SingleTypeJAXBManager;
|
||||
|
||||
|
@ -56,6 +53,8 @@ import com.raytheon.uf.common.serialization.SingleTypeJAXBManager;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Dec 01, 2016 5588 nabowle Initial creation
|
||||
* Dec 16, 2016 5588 nabowle Throw exceptions for invalid azimuth and range.
|
||||
* Jul 19, 2018 5588 mapeters Account for legacy/java decode paths using separate
|
||||
* gather dirs
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -63,7 +62,9 @@ import com.raytheon.uf.common.serialization.SingleTypeJAXBManager;
|
|||
*/
|
||||
|
||||
public abstract class MpeRadarDecoder<T extends MpeRadarFile<?>> {
|
||||
private static SingleTypeJAXBManager<MpeRadarDecoderConfig> jaxb;
|
||||
|
||||
private static final SingleTypeJAXBManager<MpeRadarDecoderConfig> JAXB = SingleTypeJAXBManager
|
||||
.createWithoutException(MpeRadarDecoderConfig.class);
|
||||
|
||||
private volatile boolean initialized;
|
||||
|
||||
|
@ -127,14 +128,14 @@ public abstract class MpeRadarDecoder<T extends MpeRadarFile<?>> {
|
|||
"Unable to retrieve the grid dir.", e);
|
||||
}
|
||||
|
||||
String prodDir = AppsDefaults.getInstance()
|
||||
.getToken(this.appsDefaultProductDir, null);
|
||||
File productDir = new File(prodDir);
|
||||
if (!Files.exists(productDir.toPath())) {
|
||||
Path prodDir = AppsDefaultsConversionWrapper
|
||||
.getPathForTokenWithoutCreating(this.appsDefaultProductDir);
|
||||
if (!Files.exists(prodDir)) {
|
||||
throw new MpeRadarDecodeException(
|
||||
"Unable to retrieve the product dir.");
|
||||
}
|
||||
|
||||
File productDir = prodDir.toFile();
|
||||
File[] files = productDir.listFiles();
|
||||
for (File file : files) {
|
||||
if (!file.isFile()) {
|
||||
|
@ -148,17 +149,10 @@ public abstract class MpeRadarDecoder<T extends MpeRadarFile<?>> {
|
|||
radarFile = loadRadarFile(path,
|
||||
MpeRadarDecodeConstants.DEFAULT_BUILD_VERSION);
|
||||
} catch (MpeRadarInputException e) {
|
||||
if (AppsDefaultsConversionWrapper.parallelExecEnabled()) {
|
||||
logger.info(
|
||||
"{} would be deleted because it is not a valid radar file.",
|
||||
path, e);
|
||||
} else {
|
||||
logger.info(
|
||||
"{} will be deleted because it is not a valid radar file.",
|
||||
path, e);
|
||||
file.delete();
|
||||
}
|
||||
|
||||
logger.info(
|
||||
"{} will be deleted because it is not a valid radar file.",
|
||||
path, e);
|
||||
file.delete();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -175,6 +169,9 @@ public abstract class MpeRadarDecoder<T extends MpeRadarFile<?>> {
|
|||
if (this.writeToDb) {
|
||||
writeRadarRecords(radarFile);
|
||||
}
|
||||
|
||||
// Successfully processed, delete the temp file
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,17 +203,8 @@ public abstract class MpeRadarDecoder<T extends MpeRadarFile<?>> {
|
|||
return;
|
||||
}
|
||||
|
||||
if (jaxb == null) {
|
||||
try {
|
||||
jaxb = new SingleTypeJAXBManager<>(MpeRadarDecoderConfig.class);
|
||||
} catch (JAXBException e) {
|
||||
logger.error("Unable to initialize the JAXB Manager.", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try (InputStream is = localizationFile.openInputStream()) {
|
||||
MpeRadarDecoderConfig config = jaxb.unmarshalFromInputStream(is);
|
||||
MpeRadarDecoderConfig config = JAXB.unmarshalFromInputStream(is);
|
||||
this.writeToDb = config.getWriteToDB();
|
||||
logger.debug("Configuration from {} has been read.",
|
||||
this.configFile);
|
||||
|
|
|
@ -39,6 +39,7 @@ import java.util.regex.Pattern;
|
|||
* Nov 22, 2016 5588 nabowle Initial creation
|
||||
* Jan 10, 2016 6058 bkowal Updated to allow extracting only the symbology
|
||||
* from a radar data file.
|
||||
* Jul 19, 2018 5588 mapeters Fix readParams() ignoring the last param
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -153,7 +154,7 @@ public class MpeRadarSymbologyData {
|
|||
private void readParams(final ByteBuffer buf, float[] paramArray,
|
||||
String parameterType) throws InvalidMpeRadarException {
|
||||
String paramStr;
|
||||
for (int i = 0; i < paramArray.length - 1; i++) {
|
||||
for (int i = 0; i < paramArray.length; i++) {
|
||||
paramStr = readNextParamString(buf);
|
||||
if (paramStr.isEmpty()) {
|
||||
paramArray[i] = EMPTY_PARAM;
|
||||
|
@ -190,7 +191,7 @@ public class MpeRadarSymbologyData {
|
|||
*/
|
||||
protected int getParametersCount(final ByteBuffer buf,
|
||||
Pattern searchPattern, String parameterType)
|
||||
throws InvalidMpeRadarException {
|
||||
throws InvalidMpeRadarException {
|
||||
char firstChar = searchPattern.toString().charAt(0);
|
||||
byte[] checkBytes = new byte[PARAM_LEN];
|
||||
buf.get(checkBytes);
|
||||
|
|
Loading…
Add table
Reference in a new issue