Merge branch 'ohd_14.4.1' of ssh://vlab.ncep.noaa.gov:29418/AWIPS2_Dev_Baseline into master_14.4.1
Former-commit-id:0bc501bd4c
[formerly0bc501bd4c
[formerly d53c809149da23fcae51138cc45c57aecd641794]] Former-commit-id:a757b55446
Former-commit-id:6cf71bae0e
This commit is contained in:
commit
953b71a3f8
6 changed files with 1255 additions and 372 deletions
|
@ -24,6 +24,7 @@ import java.io.FileInputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.channels.FileChannel;
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -35,6 +36,10 @@ import java.util.ListIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import javax.measure.converter.UnitConverter;
|
||||||
|
import javax.measure.unit.NonSI;
|
||||||
|
import javax.measure.unit.Unit;
|
||||||
|
|
||||||
import org.eclipse.swt.events.DisposeEvent;
|
import org.eclipse.swt.events.DisposeEvent;
|
||||||
import org.eclipse.swt.events.DisposeListener;
|
import org.eclipse.swt.events.DisposeListener;
|
||||||
import org.eclipse.swt.graphics.RGB;
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
@ -44,8 +49,13 @@ import org.eclipse.ui.commands.ICommandService;
|
||||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||||
|
|
||||||
import com.raytheon.uf.common.colormap.Color;
|
import com.raytheon.uf.common.colormap.Color;
|
||||||
|
import com.raytheon.uf.common.colormap.ColorMap;
|
||||||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||||
|
import com.raytheon.uf.common.colormap.prefs.DataMappingPreferences;
|
||||||
|
import com.raytheon.uf.common.colormap.prefs.DataMappingPreferences.DataMappingEntry;
|
||||||
|
import com.raytheon.uf.common.dataplugin.shef.tables.Colorvalue;
|
||||||
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
|
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
|
||||||
|
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||||
import com.raytheon.uf.common.ohd.AppsDefaults;
|
import com.raytheon.uf.common.ohd.AppsDefaults;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
import com.raytheon.uf.common.time.DataTime;
|
import com.raytheon.uf.common.time.DataTime;
|
||||||
|
@ -60,13 +70,17 @@ import com.raytheon.uf.viz.core.drawables.IFont;
|
||||||
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
|
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
|
||||||
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
|
import com.raytheon.uf.viz.core.localization.LocalizationManager;
|
||||||
import com.raytheon.uf.viz.core.rsc.GenericResourceData;
|
import com.raytheon.uf.viz.core.rsc.GenericResourceData;
|
||||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||||
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
|
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
|
||||||
import com.raytheon.viz.core.rsc.jts.JTSCompiler;
|
import com.raytheon.viz.core.rsc.jts.JTSCompiler;
|
||||||
|
import com.raytheon.viz.hydrocommon.whfslib.colorthreshold.GetColorValues;
|
||||||
|
import com.raytheon.viz.hydrocommon.whfslib.colorthreshold.NamedColorUseSet;
|
||||||
import com.raytheon.viz.mpe.MPECommandConstants;
|
import com.raytheon.viz.mpe.MPECommandConstants;
|
||||||
import com.raytheon.viz.mpe.core.MPEDataManager;
|
import com.raytheon.viz.mpe.core.MPEDataManager;
|
||||||
import com.raytheon.viz.mpe.core.MPEDataManager.MPEGageData;
|
import com.raytheon.viz.mpe.core.MPEDataManager.MPEGageData;
|
||||||
|
import com.raytheon.viz.mpe.core.MPEDataManager.MPERadarLoc;
|
||||||
import com.raytheon.viz.mpe.ui.Activator;
|
import com.raytheon.viz.mpe.ui.Activator;
|
||||||
import com.raytheon.viz.mpe.ui.DisplayFieldData;
|
import com.raytheon.viz.mpe.ui.DisplayFieldData;
|
||||||
import com.raytheon.viz.mpe.ui.IDisplayFieldChangedListener;
|
import com.raytheon.viz.mpe.ui.IDisplayFieldChangedListener;
|
||||||
|
@ -97,6 +111,8 @@ import com.vividsolutions.jts.index.strtree.STRtree;
|
||||||
* Feb 12, 2013 15773 snaples Updated addPoints to display PC gages when token is set to use PC data.
|
* Feb 12, 2013 15773 snaples Updated addPoints to display PC gages when token is set to use PC data.
|
||||||
* Mar 14, 2013 1457 mpduff Fixed various bugs.
|
* Mar 14, 2013 1457 mpduff Fixed various bugs.
|
||||||
* Apr 19, 2013 1920 mpduff Fixed gage color contrast, add e to display value of manually edited gages.
|
* Apr 19, 2013 1920 mpduff Fixed gage color contrast, add e to display value of manually edited gages.
|
||||||
|
* Dec 12, 2014 15689 cgobs Fixed problem with mismatched color set for Color by value color scale (RM 15689 = DIM 17541
|
||||||
|
* Dec 12, 2014 16748 cgobs Fixed problem with missing "d" for disagged gages (RM 16748 = DIM 17606).
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -107,6 +123,8 @@ import com.vividsolutions.jts.index.strtree.STRtree;
|
||||||
public class MPEGageResource extends AbstractMPEInputResource implements
|
public class MPEGageResource extends AbstractMPEInputResource implements
|
||||||
IDisplayFieldChangedListener {
|
IDisplayFieldChangedListener {
|
||||||
|
|
||||||
|
public static final String APPLICATION_NAME = "hmapmpe";
|
||||||
|
|
||||||
private static final String GAGE_TRIANGLES = "GAGETRIANGLES%sz";
|
private static final String GAGE_TRIANGLES = "GAGETRIANGLES%sz";
|
||||||
|
|
||||||
private static final double POINT_RADIUS = 2;
|
private static final double POINT_RADIUS = 2;
|
||||||
|
@ -126,6 +144,9 @@ public class MPEGageResource extends AbstractMPEInputResource implements
|
||||||
private final double MILLICVT = 25.4;
|
private final double MILLICVT = 25.4;
|
||||||
|
|
||||||
private ColorMapParameters parameters;
|
private ColorMapParameters parameters;
|
||||||
|
private Colorvalue[] colorvalueArray;
|
||||||
|
private float[] thresholdArray;
|
||||||
|
private RGB[] rgbArray;
|
||||||
|
|
||||||
private Display7x7Dialog dialog;
|
private Display7x7Dialog dialog;
|
||||||
|
|
||||||
|
@ -425,6 +446,15 @@ public class MPEGageResource extends AbstractMPEInputResource implements
|
||||||
if (gageData.isManedit()) {
|
if (gageData.isManedit()) {
|
||||||
gageValue = gageValue.concat("e");
|
gageValue = gageValue.concat("e");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if gageData is result of running disagg in DailyQC
|
||||||
|
// (time-distributed)
|
||||||
|
// append a "d" to the gage value
|
||||||
|
if (gageData.isTd()) {
|
||||||
|
gageValue = gageValue.concat("d");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DrawableString string = new DrawableString(
|
DrawableString string = new DrawableString(
|
||||||
new String[] { gageValue, gageId, }, gageColor);
|
new String[] { gageValue, gageId, }, gageColor);
|
||||||
string.font = font;
|
string.font = font;
|
||||||
|
@ -531,34 +561,212 @@ public class MPEGageResource extends AbstractMPEInputResource implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RGB getColorByValue(float gval) {
|
public RGB getColorByValue(float value) {
|
||||||
float value = gval;
|
|
||||||
|
|
||||||
if (value == -999.0) {
|
if (value == -999.0) {
|
||||||
value = -9999.0f;
|
value = -9999.0f;
|
||||||
}
|
}
|
||||||
Color color = parameters.getColorByValue(value);
|
|
||||||
return new RGB((int) (color.getRed() * 255),
|
int colorIndex = getColorIndex(value, thresholdArray);
|
||||||
(int) (color.getGreen() * 255), (int) (color.getBlue() * 255));
|
|
||||||
|
|
||||||
|
// System.out.println("getColorByValue(): colorIndex = " + colorIndex);
|
||||||
|
return rgbArray[colorIndex];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int getColorIndex(float value, float[] threshholdValueArray) {
|
||||||
|
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
if (threshholdValueArray == null)
|
||||||
|
{
|
||||||
|
index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (value == threshholdValueArray[0])
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (value == threshholdValueArray[1])
|
||||||
|
{
|
||||||
|
index = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
index = threshholdValueArray.length-1;
|
||||||
|
for (int i = 2 ; i < threshholdValueArray.length-1; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
if (value < threshholdValueArray[i+1])
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadColors() {
|
private void loadColors() {
|
||||||
MPEFieldResource displayedResource = displayMgr
|
|
||||||
.getDisplayedFieldResource();
|
loadColorData(
|
||||||
if (displayedResource != null) {
|
"PRECIP_ACCUM",//color value use
|
||||||
parameters = displayedResource.getCapability(
|
1, //duration in hours
|
||||||
ColorMapCapability.class).getColorMapParameters();
|
NonSI.INCH, //original data units
|
||||||
|
NonSI.INCH); //display units
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadColorData(String cvUse,
|
||||||
|
int durationInHrs, Unit<?> dataUnit, Unit<?> displayUnit)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
String header = "MPEGageResource.getColorvalueArray(): ";
|
||||||
|
|
||||||
|
if (durationInHrs == 0) {
|
||||||
|
durationInHrs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MPEDisplayManager displayMgr = MPEDisplayManager.getCurrent();
|
||||||
|
List<NamedColorUseSet> pColorSetGroup = displayMgr.getColorSetGroup();
|
||||||
|
|
||||||
|
ColorMapParameters params = new ColorMapParameters();
|
||||||
|
params.setFormatString("0.00");
|
||||||
|
params.setDisplayUnit(displayUnit);
|
||||||
|
|
||||||
|
|
||||||
|
Colorvalue[] colorSet = GetColorValues.get_colorvalues(
|
||||||
|
LocalizationManager.getContextName(LocalizationLevel.USER),
|
||||||
|
APPLICATION_NAME, cvUse, durationInHrs * 60 * 60, "E",
|
||||||
|
pColorSetGroup).toArray(new Colorvalue[0]);
|
||||||
|
|
||||||
|
int numColors = colorSet.length;
|
||||||
|
thresholdArray = new float[numColors];
|
||||||
|
rgbArray = new RGB[numColors];
|
||||||
|
|
||||||
|
for (int i = 0; i < numColors; ++i) {
|
||||||
|
|
||||||
|
Colorvalue cv = colorSet[i];
|
||||||
|
String colorName = cv.getColorname().getColorName();
|
||||||
|
RGB rgb = RGBColors.getRGBColor(colorName);
|
||||||
|
|
||||||
|
|
||||||
|
float threshold = (float) cv.getId().getThresholdValue();
|
||||||
|
|
||||||
|
thresholdArray[i] = threshold;
|
||||||
|
rgbArray[i] = rgb;
|
||||||
|
// System.out.printf(header + "threshold = %f, color = %s\n", threshold, colorName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link ColorMapParameters} object for the given
|
||||||
|
* parameters
|
||||||
|
*
|
||||||
|
* @param cvUse
|
||||||
|
* @param durationInHrs
|
||||||
|
* @param dataUnit
|
||||||
|
* @param displayUnit
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static ColorMapParameters createColorMap(String cvUse,
|
||||||
|
int durationInHrs, Unit<?> dataUnit, Unit<?> displayUnit) {
|
||||||
|
|
||||||
|
|
||||||
|
String header = "MPEGageResource.createColorMap(): ";
|
||||||
|
|
||||||
|
if (durationInHrs == 0) {
|
||||||
|
durationInHrs = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MPEDisplayManager displayMgr = MPEDisplayManager.getCurrent();
|
||||||
|
List<NamedColorUseSet> pColorSetGroup = displayMgr.getColorSetGroup();
|
||||||
|
|
||||||
|
ColorMapParameters params = new ColorMapParameters();
|
||||||
|
params.setFormatString("0.00");
|
||||||
|
params.setDisplayUnit(displayUnit);
|
||||||
|
params.setDataUnit(dataUnit);
|
||||||
|
|
||||||
|
UnitConverter displayToData = params.getDisplayToDataConverter();
|
||||||
|
UnitConverter dataToDisplay = params.getDataToDisplayConverter();
|
||||||
|
|
||||||
|
DataMappingPreferences dm = new DataMappingPreferences();
|
||||||
|
|
||||||
|
Colorvalue[] colorSet = GetColorValues.get_colorvalues(
|
||||||
|
LocalizationManager.getContextName(LocalizationLevel.USER),
|
||||||
|
APPLICATION_NAME, cvUse, durationInHrs * 60 * 60, "E",
|
||||||
|
pColorSetGroup).toArray(new Colorvalue[0]);
|
||||||
|
|
||||||
|
|
||||||
|
DecimalFormat format = new DecimalFormat(params.getFormatString());
|
||||||
|
|
||||||
|
int numColors = colorSet.length;
|
||||||
|
float[] red = new float[numColors];
|
||||||
|
float[] green = new float[numColors];
|
||||||
|
float[] blue = new float[numColors];
|
||||||
|
|
||||||
|
for (int i = 0; i < numColors; ++i) {
|
||||||
|
Colorvalue cv = colorSet[i];
|
||||||
|
String colorName = cv.getColorname().getColorName();
|
||||||
|
RGB rgb = RGBColors.getRGBColor(cv.getColorname().getColorName());
|
||||||
|
red[i] = rgb.red / 255f;
|
||||||
|
green[i] = rgb.green / 255f;
|
||||||
|
blue[i] = rgb.blue / 255f;
|
||||||
|
|
||||||
|
double threshold = cv.getId().getThresholdValue();
|
||||||
|
|
||||||
|
|
||||||
|
System.out.printf(header + "threshold = %f, color = %s\n", threshold, colorName);
|
||||||
|
|
||||||
|
DataMappingEntry entry = new DataMappingEntry();
|
||||||
|
if (threshold == -9999.0 || threshold == -8888.0) {
|
||||||
|
entry.setDisplayValue(threshold);
|
||||||
|
entry.setOperator("<");
|
||||||
|
entry.setLabel("");
|
||||||
} else {
|
} else {
|
||||||
DisplayFieldData displayedData = displayMgr.getDisplayFieldType();
|
// Convert display to data, cast to int, convert back to display
|
||||||
parameters = MPEDisplayManager
|
entry.setDisplayValue(dataToDisplay.convert((int) displayToData
|
||||||
.createColorMap(displayedData.getCv_use(), displayedData
|
.convert(threshold)));
|
||||||
.getCv_duration(), MPEFieldResourceData
|
|
||||||
.getDataUnitsForField(displayedData),
|
|
||||||
MPEFieldResourceData
|
|
||||||
.getDisplayUnitsForField(displayedData));
|
|
||||||
}
|
}
|
||||||
|
entry.setPixelValue((double) i);
|
||||||
|
|
||||||
|
dm.addEntry(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DataMappingEntry entry = new DataMappingEntry();
|
||||||
|
entry.setDisplayValue(Double.MAX_VALUE);
|
||||||
|
entry.setPixelValue((double) (numColors - 1));
|
||||||
|
entry.setLabel("");
|
||||||
|
dm.addEntry(entry);
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inspect method called when moused over while inspect is enabled
|
* Inspect method called when moused over while inspect is enabled
|
||||||
*
|
*
|
||||||
|
@ -658,4 +866,7 @@ public class MPEGageResource extends AbstractMPEInputResource implements
|
||||||
reloadGages();
|
reloadGages();
|
||||||
issueRefresh();
|
issueRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,6 +182,42 @@ MpeRUCFreezingLevel : ON
|
||||||
MpeLightningSrv : ON
|
MpeLightningSrv : ON
|
||||||
#====================================================================================
|
#====================================================================================
|
||||||
|
|
||||||
|
#===================== run_report_alarm Configuration ===============================
|
||||||
|
# These settings modify behavior of the EDEX RunReportAlarmSrv service, which
|
||||||
|
# replaced the original run_report_alarm script ported from A1 hydro.
|
||||||
|
#
|
||||||
|
## Mandatory Arguments:
|
||||||
|
## alarm_product_id : The product id that will be used to write the alarm
|
||||||
|
## report product into the textdb.
|
||||||
|
##
|
||||||
|
## Optional Arguments:
|
||||||
|
## alarm_file_suffix : A Java date/time format string that will be used as
|
||||||
|
## the alarm report's file extension when the product is
|
||||||
|
## written to disk. Product file path is
|
||||||
|
## ${whfs_product_dir}/PRODUCT_ID.FILE_SUFFIX.
|
||||||
|
##
|
||||||
|
## alarm_report_mode : Report mode. Valid values are one of the following:
|
||||||
|
## ALL, FRESH, RECENT, UNREPORTED, NEAREST, NEAR_NOW,
|
||||||
|
## LATEST_MAXFCST, or NEW_OR_INCREASED.
|
||||||
|
##
|
||||||
|
## alarm_filter : Additional filtering options for the product.
|
||||||
|
## Valid values can one or many of the following:
|
||||||
|
## 'O', 'F', 'T', 'M', 'R', 'L', 'U', 'D'.
|
||||||
|
##
|
||||||
|
## alarm_pe_filter : Physical element filter.
|
||||||
|
##
|
||||||
|
## alarm_minutes : For certain report modes, creates a window going back
|
||||||
|
## or forward the specified number of minutes.
|
||||||
|
## Valid values are 1 - 999999.
|
||||||
|
##
|
||||||
|
## alarm_verbose : Whether or not to create a "verbose mode" report.
|
||||||
|
## Valid values are TRUE or FALSE.
|
||||||
|
##
|
||||||
|
|
||||||
|
alarm_product_id : CCCACRXXX
|
||||||
|
alarm_file_suffix : MMdd.HHmm
|
||||||
|
alarm_report_mode : NEAREST
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
|
|
||||||
# Executable directory tokens.
|
# Executable directory tokens.
|
||||||
|
@ -207,7 +243,7 @@ server_name : ONLINE # Informix database server name
|
||||||
db_name : hd_ob92lwx # IHFS database name
|
db_name : hd_ob92lwx # IHFS database name
|
||||||
damcat_db_name : dc_ob5xxx # Dam Catalog database name
|
damcat_db_name : dc_ob5xxx # Dam Catalog database name
|
||||||
hdb_db_name : ob81_histdata # Historical database.
|
hdb_db_name : ob81_histdata # Historical database.
|
||||||
pghost : localhost # The machine PostGres is running on
|
pghost : dx1f # The machine PostGres is running on
|
||||||
pguser : awips # The user allowed to access PostGres
|
pguser : awips # The user allowed to access PostGres
|
||||||
pgport : 5432 # The PostGres Server port
|
pgport : 5432 # The PostGres Server port
|
||||||
adb_name : adb_ob7xxx # RFC archive database name
|
adb_name : adb_ob7xxx # RFC archive database name
|
||||||
|
@ -1896,7 +1932,11 @@ mpe_post_output : $(mpe_fieldgen_product_dir)/post_analysis
|
||||||
# add ,RDMOSAIC,BDMOSAIC,LDMOSAIC,MDMOSAIC,MLDMOSAIC,AVGRDMOSAIC,MAXRDMOSAIC,SRDMOSAIC,SRDGMOSAIC to existing mpe_generate_list token
|
# add ,RDMOSAIC,BDMOSAIC,LDMOSAIC,MDMOSAIC,MLDMOSAIC,AVGRDMOSAIC,MAXRDMOSAIC,SRDMOSAIC,SRDGMOSAIC to existing mpe_generate_list token
|
||||||
|
|
||||||
# ================== end of SSHP Directory Structure tokens ========================
|
# ================== end of SSHP Directory Structure tokens ========================
|
||||||
|
# nrldb tokens
|
||||||
|
nrldb_log : $(whfs_log_dir)/nrldb
|
||||||
|
nrldb_data : $(whfs_local_data_dir)/nrldb
|
||||||
|
nrldb_config : $(whfs_config_dir)/nrldb
|
||||||
|
nrldb_tmp : /awips/hydroapps/whfs/local/data/output
|
||||||
|
|
||||||
# The syntax needed in the file is:
|
# The syntax needed in the file is:
|
||||||
#
|
#
|
||||||
|
|
|
@ -43,8 +43,8 @@ import com.raytheon.uf.common.dataplugin.shef.util.ShefConstants;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* June 15, 2011 9377 jnjanga Initial creation
|
* June 15, 2011 9377 jnjanga Initial creation
|
||||||
*
|
* October 20, 2014 DR DIM#17259 deng fix false alert/alarm are generated with
|
||||||
*
|
* NEW_OR_INCREASED mode
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jnjanga
|
* @author jnjanga
|
||||||
|
@ -64,7 +64,6 @@ class AlertalarmRecord {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AlertalarmRecord newInstance() {
|
public static AlertalarmRecord newInstance() {
|
||||||
if (instance == null)
|
|
||||||
instance = new AlertalarmRecord();
|
instance = new AlertalarmRecord();
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -40,6 +42,7 @@ import com.raytheon.uf.common.dataplugin.shef.tables.Counties;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.tables.CountiesId;
|
import com.raytheon.uf.common.dataplugin.shef.tables.CountiesId;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.tables.Datalimits;
|
import com.raytheon.uf.common.dataplugin.shef.tables.Datalimits;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.tables.DatalimitsId;
|
import com.raytheon.uf.common.dataplugin.shef.tables.DatalimitsId;
|
||||||
|
import com.raytheon.uf.common.dataplugin.shef.tables.Descrip;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.tables.Hsa;
|
import com.raytheon.uf.common.dataplugin.shef.tables.Hsa;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.tables.Location;
|
import com.raytheon.uf.common.dataplugin.shef.tables.Location;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.tables.Network;
|
import com.raytheon.uf.common.dataplugin.shef.tables.Network;
|
||||||
|
@ -47,6 +50,8 @@ import com.raytheon.uf.common.dataplugin.shef.tables.Rfc;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.tables.State;
|
import com.raytheon.uf.common.dataplugin.shef.tables.State;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.tables.Timezone;
|
import com.raytheon.uf.common.dataplugin.shef.tables.Timezone;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.tables.Wfo;
|
import com.raytheon.uf.common.dataplugin.shef.tables.Wfo;
|
||||||
|
import com.raytheon.uf.common.dataplugin.shef.tables.Riverstat;
|
||||||
|
import com.raytheon.uf.common.dataplugin.shef.tables.Shefpe;
|
||||||
import com.raytheon.uf.common.dataplugin.shef.util.ShefConstants;
|
import com.raytheon.uf.common.dataplugin.shef.util.ShefConstants;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
@ -55,6 +60,7 @@ import com.raytheon.uf.common.util.CollectionUtil;
|
||||||
import com.raytheon.uf.edex.database.dao.CoreDao;
|
import com.raytheon.uf.edex.database.dao.CoreDao;
|
||||||
import com.raytheon.uf.edex.database.dao.DaoConfig;
|
import com.raytheon.uf.edex.database.dao.DaoConfig;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
|
@ -67,6 +73,8 @@ import com.raytheon.uf.edex.database.dao.DaoConfig;
|
||||||
* Sep 05, 2013 16539 wkwock Fix RECENT, NEAR_NOW,FRESH,and NEW_OR_INCREASED modes
|
* Sep 05, 2013 16539 wkwock Fix RECENT, NEAR_NOW,FRESH,and NEW_OR_INCREASED modes
|
||||||
* Feb 13, 2014 #2783 dgilling Refactored to support running as part
|
* Feb 13, 2014 #2783 dgilling Refactored to support running as part
|
||||||
* of an EDEX service.
|
* of an EDEX service.
|
||||||
|
* Oct 20, 2014 DIM#16799 deng missing forecast report for FRESH mode
|
||||||
|
* Oct 20, 2014 DIM#17605 deng mismatch report format between A1 and A2
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -90,6 +98,8 @@ class ReportWriter {
|
||||||
|
|
||||||
private Date endTime;
|
private Date endTime;
|
||||||
|
|
||||||
|
private String[] limitThreshold;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
|
@ -98,6 +108,7 @@ class ReportWriter {
|
||||||
*/
|
*/
|
||||||
ReportWriter(ReportOptions opt, Date now) {
|
ReportWriter(ReportOptions opt, Date now) {
|
||||||
this.reportData = new StringBuilder();
|
this.reportData = new StringBuilder();
|
||||||
|
this.limitThreshold = new String[] {"","","","","","","",""};
|
||||||
this.opt = opt;
|
this.opt = opt;
|
||||||
this.now = now;
|
this.now = now;
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
@ -151,23 +162,51 @@ class ReportWriter {
|
||||||
writeNewline();
|
writeNewline();
|
||||||
writeNewline();
|
writeNewline();
|
||||||
|
|
||||||
write("CREATED AT : " + now.toString());
|
// start to change for mismatch between A1 and A2, make sure the now is GMtime
|
||||||
|
write("CREATED " + opt.getProductId() + " AT : " + now.toString());
|
||||||
writeNewline();
|
writeNewline();
|
||||||
write("PRODUCT ID : " + opt.getProductId());
|
}
|
||||||
|
|
||||||
|
private void writeReportTrailer() {
|
||||||
|
/* if no alarms found, then write message */
|
||||||
|
|
||||||
|
if (alarmCount == 0) {
|
||||||
|
writeln("\nNO ALERT/ALARM DATA TO REPORT FOR GIVEN REQUEST.\n");
|
||||||
|
} else {
|
||||||
|
String reportMode = opt.getMode().toString();
|
||||||
|
if (reportMode.equals("")) {
|
||||||
|
writeln("\n" + alarmCount + " ALERT/ALARMS REPORTED.");
|
||||||
|
} else {
|
||||||
|
writeln("\n" + alarmCount + " ALERT/ALARMS REPORTED. ("
|
||||||
|
+ reportMode + " MODE)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeln("\nEND OF REPORT");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the report's trailer information.
|
||||||
|
*/
|
||||||
|
private void writeVerboseTrailer() {
|
||||||
|
|
||||||
|
if (alarmCount == 0) {
|
||||||
writeNewline();
|
writeNewline();
|
||||||
|
write("NO ALERT/ALARM DATA TO REPORT FOR GIVEN REQUEST.");
|
||||||
// write a phrase describing the report mode.
|
|
||||||
// the modes which consider the action_time are:
|
|
||||||
// UNREPORTED, FRESH, NEW_OR_INCREASED.
|
|
||||||
// The ones that don't consider it are:
|
|
||||||
// ALL, RECENT, NEAREST, NEAR_NOW, LATEST_MAXFCST
|
|
||||||
|
|
||||||
write("REPORT MODE: " + opt.getMode().toString());
|
|
||||||
write(" (see end of report for mode description).");
|
|
||||||
writeNewline();
|
writeNewline();
|
||||||
|
writeNewline();
|
||||||
|
} else {
|
||||||
|
String reportMode = opt.getMode().toString();
|
||||||
|
if (reportMode.equals("")) {
|
||||||
|
writeln("\n" + alarmCount + " ALERT/ALARMS REPORTED.");
|
||||||
|
} else {
|
||||||
|
writeln("\n" + alarmCount + " ALERT/ALARMS REPORTED. ("
|
||||||
|
+ reportMode + " MODE)");
|
||||||
|
}
|
||||||
|
writeln("\n-------------------------------------------------------------------");
|
||||||
|
|
||||||
|
/* add to match A1 format*/
|
||||||
|
|
||||||
// note which class of data is being considered via the filter
|
|
||||||
write("DATA FILTER: ");
|
write("DATA FILTER: ");
|
||||||
|
|
||||||
EnumSet<FilterOption> flags = opt.getFilter();
|
EnumSet<FilterOption> flags = opt.getFilter();
|
||||||
|
@ -229,45 +268,7 @@ class ReportWriter {
|
||||||
|
|
||||||
writeNewline();
|
writeNewline();
|
||||||
writeln("--------------------------------------------------------------------");
|
writeln("--------------------------------------------------------------------");
|
||||||
}
|
|
||||||
|
|
||||||
private void writeReportTrailer() {
|
|
||||||
/* if no alarms found, then write message */
|
|
||||||
|
|
||||||
if (alarmCount == 0) {
|
|
||||||
writeln("\nNO ALERT/ALARM DATA TO REPORT FOR GIVEN REQUEST.\n");
|
|
||||||
} else {
|
|
||||||
String reportMode = opt.getMode().toString();
|
|
||||||
if (reportMode.equals("")) {
|
|
||||||
writeln("\n" + alarmCount + " ALERT/ALARMS REPORTED.");
|
|
||||||
} else {
|
|
||||||
writeln("\n" + alarmCount + " ALERT/ALARMS REPORTED. ("
|
|
||||||
+ reportMode + " MODE)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writeln("\nEND OF REPORT");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the report's trailer information.
|
|
||||||
*/
|
|
||||||
private void writeVerboseTrailer() {
|
|
||||||
|
|
||||||
if (alarmCount == 0) {
|
|
||||||
writeNewline();
|
|
||||||
write("NO ALERT/ALARM DATA TO REPORT FOR GIVEN REQUEST.");
|
|
||||||
writeNewline();
|
|
||||||
writeNewline();
|
|
||||||
} else {
|
|
||||||
String reportMode = opt.getMode().toString();
|
|
||||||
if (reportMode.equals("")) {
|
|
||||||
writeln("\n" + alarmCount + " ALERT/ALARMS REPORTED.");
|
|
||||||
} else {
|
|
||||||
writeln("\n" + alarmCount + " ALERT/ALARMS REPORTED. ("
|
|
||||||
+ reportMode + " MODE)");
|
|
||||||
}
|
|
||||||
writeln("\n-------------------------------------------------------------------");
|
|
||||||
writeln("Limits: shown above are the alert threshold/alarm threshold.");
|
writeln("Limits: shown above are the alert threshold/alarm threshold.");
|
||||||
writeln("Info grouped by location, physical element, type-source and check type.");
|
writeln("Info grouped by location, physical element, type-source and check type.");
|
||||||
writeln("Upper, lower, diff and rate-of-change (roc) limits are shown for each group.");
|
writeln("Upper, lower, diff and rate-of-change (roc) limits are shown for each group.");
|
||||||
|
@ -345,6 +346,13 @@ class ReportWriter {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private void writeGroup(List<Alertalarmval> grpData) throws Exception {
|
private void writeGroup(List<Alertalarmval> grpData) throws Exception {
|
||||||
|
|
||||||
|
/* determine this grpData is observed or forecast, if forecast, need to reserve the order */
|
||||||
|
|
||||||
|
char grpTs0 = grpData.get(0).getId().getTs().charAt(0);
|
||||||
|
if (grpTs0 != 'R' && grpTs0 != 'P') {
|
||||||
|
Collections.reverse(grpData);
|
||||||
|
}
|
||||||
if (hasDataToReport(grpData)) {
|
if (hasDataToReport(grpData)) {
|
||||||
/* write the alert-alarm group header */
|
/* write the alert-alarm group header */
|
||||||
writeGroupHeader(grpData);
|
writeGroupHeader(grpData);
|
||||||
|
@ -392,10 +400,9 @@ class ReportWriter {
|
||||||
*/
|
*/
|
||||||
private void writeGroupReport(List<Alertalarmval> grpData) throws Exception {
|
private void writeGroupReport(List<Alertalarmval> grpData) throws Exception {
|
||||||
|
|
||||||
Alertalarmval maxfcst = findMaxfcst(grpData);
|
|
||||||
Alertalarmval latestReport = findLatestAction(grpData);
|
|
||||||
Date posttime = null;
|
Date posttime = null;
|
||||||
double latestValue = -88888.;
|
double latestValue = -88888.;
|
||||||
|
Boolean maxFcstActionTimeNullFlag = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* processing starts with the first record for this group if processing
|
* processing starts with the first record for this group if processing
|
||||||
|
@ -406,9 +413,10 @@ class ReportWriter {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char grpTs0 = grpData.get(0).getId().getTs().charAt(0);
|
char grpTs0 = grpData.get(0).getId().getTs().charAt(0);
|
||||||
if (grpTs0 != 'R' && grpTs0 != 'P') {
|
|
||||||
Collections.reverse(grpData);
|
/* consider the reverse order for forecast, move to after modify 09/12/2014 */
|
||||||
}
|
Alertalarmval maxfcst = findMaxfcst(grpData);
|
||||||
|
Alertalarmval latestReport = findLatestAction(grpData);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* now loop on the data for this group and write the data records
|
* now loop on the data for this group and write the data records
|
||||||
|
@ -498,7 +506,6 @@ class ReportWriter {
|
||||||
* value
|
* value
|
||||||
*/
|
*/
|
||||||
for (Alertalarmval aav : grpData) {
|
for (Alertalarmval aav : grpData) {
|
||||||
|
|
||||||
if ((grpTs0 == 'R' || grpTs0 == 'P')) {
|
if ((grpTs0 == 'R' || grpTs0 == 'P')) {
|
||||||
Date validtime = aav.getId().getValidtime();
|
Date validtime = aav.getId().getValidtime();
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
@ -514,9 +521,15 @@ class ReportWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (grpTs0 == 'F' || grpTs0 == 'C') {
|
if (grpTs0 == 'F' || grpTs0 == 'C') {
|
||||||
if (maxfcst != null
|
if (maxfcst != null) {
|
||||||
&& isNotNull(maxfcst.getActionTime().getTime())) {
|
|
||||||
if (maxfcst.getActionTime().before(startTime)) {
|
if (isNull(maxfcst.getActionTime().getTime())) {
|
||||||
|
maxFcstActionTimeNullFlag = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
maxFcstActionTimeNullFlag = false;
|
||||||
|
|
||||||
|
if (maxFcstActionTimeNullFlag == true || maxfcst.getActionTime().before(startTime)) {
|
||||||
writeAAval(maxfcst);
|
writeAAval(maxfcst);
|
||||||
updateDatabase(maxfcst);
|
updateDatabase(maxfcst);
|
||||||
alarmCount++;
|
alarmCount++;
|
||||||
|
@ -536,7 +549,8 @@ class ReportWriter {
|
||||||
cal.setTimeInMillis(0);
|
cal.setTimeInMillis(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNull(aav.getActionTime().getTime())) {
|
if (isNull(aav.getActionTime().getTime()))
|
||||||
|
{
|
||||||
posttime = aav.getPostingtime();
|
posttime = aav.getPostingtime();
|
||||||
/*
|
/*
|
||||||
* if the record was posted after the last posted report
|
* if the record was posted after the last posted report
|
||||||
|
@ -544,6 +558,7 @@ class ReportWriter {
|
||||||
* has a higher value than the last posted record's value
|
* has a higher value than the last posted record's value
|
||||||
* (i.e. the report is 'increased'), then report it.
|
* (i.e. the report is 'increased'), then report it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cal.add(Calendar.MINUTE, opt.getMinutes());
|
cal.add(Calendar.MINUTE, opt.getMinutes());
|
||||||
|
|
||||||
if (posttime.after(cal.getTime())
|
if (posttime.after(cal.getTime())
|
||||||
|
@ -586,11 +601,12 @@ class ReportWriter {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Alertalarmval latestReport = findLatestAction(grpData);
|
|
||||||
Alertalarmval maxfcstVal = findMaxfcst(grpData);
|
|
||||||
Date posttime = null;
|
Date posttime = null;
|
||||||
double latestValue = -88888.;
|
double latestValue = -88888.;
|
||||||
|
|
||||||
|
Alertalarmval maxfcstVal = findMaxfcst(grpData);
|
||||||
|
Alertalarmval latestReport = findLatestAction(grpData);
|
||||||
|
|
||||||
// The following mode are more restrictive
|
// The following mode are more restrictive
|
||||||
for (Alertalarmval aav : grpData) {
|
for (Alertalarmval aav : grpData) {
|
||||||
char ts0 = aav.getId().getTs().charAt(0);
|
char ts0 = aav.getId().getTs().charAt(0);
|
||||||
|
@ -637,6 +653,9 @@ class ReportWriter {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (maxfcstVal != null && isNull(maxfcstVal.getActionTime().getTime())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -650,7 +669,8 @@ class ReportWriter {
|
||||||
cal.setTimeInMillis(0);
|
cal.setTimeInMillis(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNull(aav.getActionTime().getTime())) {
|
if (isNull(aav.getActionTime().getTime()))
|
||||||
|
{
|
||||||
posttime = aav.getPostingtime();
|
posttime = aav.getPostingtime();
|
||||||
/*
|
/*
|
||||||
* if the record was posted after the last posted report
|
* if the record was posted after the last posted report
|
||||||
|
@ -658,6 +678,7 @@ class ReportWriter {
|
||||||
* has a higher value than the last posted record's value
|
* has a higher value than the last posted record's value
|
||||||
* (i.e. the report is 'increased'), then report it.
|
* (i.e. the report is 'increased'), then report it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
cal.add(Calendar.MINUTE, opt.getMinutes());
|
cal.add(Calendar.MINUTE, opt.getMinutes());
|
||||||
|
|
||||||
if (posttime.after(cal.getTime())) {
|
if (posttime.after(cal.getTime())) {
|
||||||
|
@ -666,7 +687,6 @@ class ReportWriter {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -684,26 +704,72 @@ class ReportWriter {
|
||||||
*/
|
*/
|
||||||
private void writeAAval(Alertalarmval aav) throws Exception {
|
private void writeAAval(Alertalarmval aav) throws Exception {
|
||||||
String[] devb = buildString(aav);
|
String[] devb = buildString(aav);
|
||||||
|
|
||||||
String durInfo = devb[0];
|
String durInfo = devb[0];
|
||||||
String exInfo = devb[1];
|
String exInfo = devb[1];
|
||||||
String validInfo = devb[2];
|
String validInfo = devb[2];
|
||||||
String basisInfo = devb[3];
|
String tsInfo = devb[3];
|
||||||
|
String peInfo = devb[4];
|
||||||
String line = null;
|
String line = null;
|
||||||
String fmtSpecifier = null;
|
String fmtSpecifier = null;
|
||||||
|
|
||||||
ArrayList<Object> args = new ArrayList<Object>();
|
ArrayList<Object> args = new ArrayList<Object>();
|
||||||
|
args.add(tsInfo);
|
||||||
|
args.add(peInfo);
|
||||||
|
args.add(aav.getValue());
|
||||||
|
args.add(validInfo);
|
||||||
|
/* args.add(aav.getId().getAaCheck());
|
||||||
|
args.add(aav.getId().getAaCateg());*/
|
||||||
|
|
||||||
|
if (aav.getId().getAaCheck().equals(ShefConstants.UPPER_CHECKSTR)) {
|
||||||
args.add(aav.getId().getAaCheck());
|
args.add(aav.getId().getAaCheck());
|
||||||
args.add(aav.getId().getAaCateg());
|
args.add(aav.getId().getAaCateg());
|
||||||
args.add(validInfo);
|
if (aav.getId().getAaCateg().equals(ShefConstants.ALARM_CATEGSTR)) {
|
||||||
args.add(aav.getValue());
|
args.add(limitThreshold[1]);
|
||||||
args.add(basisInfo);
|
} else {
|
||||||
if (aav.getId().getAaCheck().equals(ShefConstants.UPPER_CHECKSTR)) {
|
args.add(limitThreshold[0]);
|
||||||
fmtSpecifier = " %s > %s %s %7.1f %s";
|
}
|
||||||
|
|
||||||
|
fmtSpecifier = "%s %s %7.1f at %s > %s %s %s";
|
||||||
} else if (aav.getId().getAaCheck()
|
} else if (aav.getId().getAaCheck()
|
||||||
.equals(ShefConstants.LOWER_CHECKSTR)) {
|
.equals(ShefConstants.LOWER_CHECKSTR)) {
|
||||||
fmtSpecifier = " %s < %s %s %7.1f %s";
|
args.add(aav.getId().getAaCheck());
|
||||||
|
args.add(aav.getId().getAaCateg());
|
||||||
|
|
||||||
|
if (aav.getId().getAaCateg().equals(ShefConstants.ALARM_CATEGSTR)) {
|
||||||
|
args.add(limitThreshold[3]);
|
||||||
} else {
|
} else {
|
||||||
fmtSpecifier = " %s > %s %s %7.1f (value = %7.1f) %s";
|
args.add(limitThreshold[2]);
|
||||||
args.add(3, aav.getSupplValue());
|
}
|
||||||
|
|
||||||
|
fmtSpecifier = "%s %s %7.1f at %s < %s %s %s";
|
||||||
|
} else if (aav.getId().getAaCheck().equals(ShefConstants.ROC_CHECKSTR)){
|
||||||
|
args.add(4, aav.getSupplValue());
|
||||||
|
args.add(aav.getId().getAaCateg());
|
||||||
|
if (aav.getId().getAaCateg().equals(ShefConstants.ALARM_CATEGSTR)) {
|
||||||
|
args.add(limitThreshold[5]);
|
||||||
|
} else {
|
||||||
|
args.add(limitThreshold[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fmtSpecifier = "%s %s %7.1f at %s Chg=%7.1f/hr > %s %s/hr";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
args.add(0,"Obs");
|
||||||
|
args.add(1,peInfo);
|
||||||
|
args.add(2, aav.getSupplValue());
|
||||||
|
args.add(3,aav.getValue());
|
||||||
|
args.add(4, validInfo);
|
||||||
|
args.add(5, aav.getId().getAaCheck());
|
||||||
|
args.add(6, aav.getId().getAaCateg());
|
||||||
|
|
||||||
|
if (aav.getId().getAaCateg().equals(ShefConstants.ALARM_CATEGSTR)) {
|
||||||
|
args.add(7, limitThreshold[7]);
|
||||||
|
} else {
|
||||||
|
args.add(7, limitThreshold[6]);
|
||||||
|
}
|
||||||
|
fmtSpecifier = "%s %s %7.1f Fcst %7.1f at %s > %s %s %s";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
statusHandler.debug("fmt=" + fmtSpecifier);
|
statusHandler.debug("fmt=" + fmtSpecifier);
|
||||||
|
@ -711,11 +777,12 @@ class ReportWriter {
|
||||||
|
|
||||||
line = String.format(fmtSpecifier, args.toArray());
|
line = String.format(fmtSpecifier, args.toArray());
|
||||||
write(line);
|
write(line);
|
||||||
|
|
||||||
if (durInfo.length() > 0 || exInfo.length() > 0) {
|
if (durInfo.length() > 0 || exInfo.length() > 0) {
|
||||||
writeln(durInfo + exInfo);
|
writeln("(" + "dur=" + durInfo + Constants.SPACE + "extr=" + exInfo + Constants.SPACE + ")");
|
||||||
} else {
|
|
||||||
writeNewline();
|
|
||||||
}
|
}
|
||||||
|
writeNewline();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -726,21 +793,21 @@ class ReportWriter {
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private String[] buildString(Alertalarmval aav) throws Exception {
|
private String[] buildString(Alertalarmval aav) throws Exception {
|
||||||
String[] devbStr = new String[4];
|
String[] devbStr = new String[5];
|
||||||
|
|
||||||
/* build a presentable string for the duration code value */
|
/* build a presentable string for the duration code value */
|
||||||
short dur = aav.getId().getDur();
|
short dur = aav.getId().getDur();
|
||||||
if (dur != 0) {
|
if (dur != 0) {
|
||||||
Object[] durData = getShefDurInfo(dur);
|
Object[] durData = getShefDurInfo(dur);
|
||||||
if (durData == null) {
|
if (durData == null) {
|
||||||
devbStr[0] = "Duration=" + dur;
|
devbStr[0] = Short.toString(dur);
|
||||||
} else {
|
} else {
|
||||||
Object[] aDurData = (Object[]) durData[0];
|
Object[] aDurData = (Object[]) durData[0];
|
||||||
devbStr[0] = (String) aDurData[2] + Constants.SPACE;
|
devbStr[0] = (String) aDurData[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
devbStr[0] = Constants.SPACE;
|
devbStr[0] = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build a presentable string for the extremum code value */
|
/* build a presentable string for the extremum code value */
|
||||||
|
@ -748,35 +815,49 @@ class ReportWriter {
|
||||||
if (!ex.equals("Z")) {
|
if (!ex.equals("Z")) {
|
||||||
Object[] exData = getShefExInfo(ex);
|
Object[] exData = getShefExInfo(ex);
|
||||||
if (exData == null) {
|
if (exData == null) {
|
||||||
devbStr[1] = "Extremum=" + ex;
|
devbStr[1] = ex;
|
||||||
} else {
|
} else {
|
||||||
devbStr[1] = (String) exData[1] + Constants.SPACE;
|
Object[] aExData = (Object[]) exData[0];
|
||||||
|
devbStr[1] = (String) aExData[0];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
devbStr[1] = Constants.SPACE;
|
devbStr[1] = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* convert the valid time for use in the update statement and for
|
* convert the valid time for use in the update statement and for
|
||||||
* presenting the time in the output
|
* presenting the time in the output
|
||||||
*/
|
*/
|
||||||
devbStr[2] = TimeUtil.formatToSqlTimestamp(aav.getId().getValidtime());
|
String validTimeStr = aav.getId().getValidtime().toString();
|
||||||
|
devbStr[2] = validTimeStr.substring(0,3) + "-" + validTimeStr.substring(4, 7) +
|
||||||
|
validTimeStr.substring(8, 10) +"-" + validTimeStr.substring(11, 16);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if forecast or contingency data, then show the basis time in a
|
* if forecast or contingency data, then show "Fcst", otherwise show "Obs"
|
||||||
* presentable fashion. also convert the basis time for use in the
|
|
||||||
* update statement later.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char ts0 = aav.getId().getTs().charAt(0);
|
char ts0 = aav.getId().getTs().charAt(0);
|
||||||
if (ts0 == 'F' || ts0 == 'C') {
|
if (ts0 == 'F' || ts0 == 'C') {
|
||||||
String basisStr = TimeUtil.formatToSqlTimestamp(aav.getId()
|
devbStr[3] = "Fcst";
|
||||||
.getBasistime());
|
|
||||||
devbStr[3] = "fcast " + basisStr;
|
|
||||||
} else {
|
} else {
|
||||||
devbStr[3] = Constants.SPACE;
|
devbStr[3] = "Obs";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* build the pe name string */
|
||||||
|
|
||||||
|
Shefpe peinfo = getShefPeInfo(aav.getId().getPe());
|
||||||
|
|
||||||
|
String peNameStr = null;
|
||||||
|
|
||||||
|
if (peinfo == null) {
|
||||||
|
peNameStr = "UndefinedName";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
peNameStr = peinfo.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
devbStr[4] = peNameStr;
|
||||||
|
|
||||||
return devbStr;
|
return devbStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -795,13 +876,40 @@ class ReportWriter {
|
||||||
|
|
||||||
State state = getStateInfo(loc.getCounties().getId().getState());
|
State state = getStateInfo(loc.getCounties().getId().getState());
|
||||||
|
|
||||||
|
// get stream name from RiverStat table
|
||||||
|
Riverstat rs = getRiverStatInfo(lid);
|
||||||
|
String streamStr = null;
|
||||||
|
if (rs == null || rs.getStream() == null)
|
||||||
|
streamStr = "";
|
||||||
|
else
|
||||||
|
streamStr = rs.getStream() + Constants.SPACE;
|
||||||
|
|
||||||
|
//get proximity field from Descrip table
|
||||||
|
String proximityStr = getDescripInfo(lid);
|
||||||
|
|
||||||
// get a description for this physical element
|
// get a description for this physical element
|
||||||
String pe = grpData.get(0).getId().getPe();
|
String pe = grpData.get(0).getId().getPe();
|
||||||
String peInfo = getShefPeInfo(pe);
|
Shefpe peinfo = getShefPeInfo(pe);
|
||||||
|
|
||||||
|
// String peNameStr = null;
|
||||||
|
String engunitStr = null;
|
||||||
|
|
||||||
|
if (peinfo == null) {
|
||||||
|
// peNameStr = "UndefinedName";
|
||||||
|
pe = "UndefinedName";
|
||||||
|
engunitStr = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// peNameStr = peinfo.getName();
|
||||||
|
engunitStr = Constants.SPACE + peinfo.getEngUnit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// make a description of the type portion of the type-source field
|
// make a description of the type portion of the type-source field
|
||||||
String typeInfo = null;
|
|
||||||
String ts = grpData.get(0).getId().getTs();
|
String ts = grpData.get(0).getId().getTs();
|
||||||
|
|
||||||
|
String typeInfo = null;
|
||||||
String ts1StChr = ts.substring(0, 1).toUpperCase();
|
String ts1StChr = ts.substring(0, 1).toUpperCase();
|
||||||
if (ts1StChr.equals("C")) {
|
if (ts1StChr.equals("C")) {
|
||||||
typeInfo = "Contingengy";
|
typeInfo = "Contingengy";
|
||||||
|
@ -815,70 +923,102 @@ class ReportWriter {
|
||||||
|
|
||||||
// write header lines to the file for this group
|
// write header lines to the file for this group
|
||||||
writeNewline();
|
writeNewline();
|
||||||
write(loc.getName() + Constants.SPACE + "(" + loc.getLid() + ")"
|
|
||||||
|
/* match A1 latest format */
|
||||||
|
|
||||||
|
if (!streamStr.equalsIgnoreCase("") && proximityStr != null)
|
||||||
|
write(streamStr + proximityStr + loc.getName() + Constants.SPACE +
|
||||||
|
"(" + loc.getLid() + ")"
|
||||||
+ Constants.SPACE + loc.getCounties().getId().getCounty()
|
+ Constants.SPACE + loc.getCounties().getId().getCounty()
|
||||||
+ " County," + Constants.SPACE + state.getName());
|
+ " County," + Constants.SPACE + state.getState() + Constants.SPACE + "(" +
|
||||||
writeNewline();
|
pe + Constants.SPACE + ts + engunitStr + ")");
|
||||||
writeNewline();
|
else if (loc.getName() != null)
|
||||||
write(peInfo + Constants.SPACE + typeInfo + Constants.SPACE + "(" + pe
|
write(loc.getName() + Constants.SPACE +
|
||||||
+ Constants.SPACE + ts + ")");
|
"(" + loc.getLid() + ")"
|
||||||
|
+ Constants.SPACE + loc.getCounties().getId().getCounty()
|
||||||
|
+ " County," + Constants.SPACE + state.getState() + Constants.SPACE + "(" +
|
||||||
|
pe + Constants.SPACE + ts + engunitStr + ")");
|
||||||
|
else
|
||||||
|
write("(" + loc.getLid() + ")"
|
||||||
|
+ Constants.SPACE + loc.getCounties().getId().getCounty()
|
||||||
|
+ " County," + Constants.SPACE + state.getState() + Constants.SPACE + "(" +
|
||||||
|
pe + Constants.SPACE + ts + engunitStr + ")");
|
||||||
|
|
||||||
writeNewline();
|
writeNewline();
|
||||||
|
|
||||||
Datalimits limits = getDatalimits(grpData);
|
Datalimits limits = getDatalimits(grpData);
|
||||||
|
|
||||||
if (limits != null) {
|
if (limits != null) {
|
||||||
|
|
||||||
StringBuilder lim = new StringBuilder("Limits: Upper limit Value=");
|
StringBuilder lim = new StringBuilder("Limits: Upper ");
|
||||||
if (limits.getAlertUpperLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
if (limits.getAlertUpperLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
||||||
lim.append(String.format("%.1f", limits.getAlertUpperLimit()));
|
lim.append(String.format("%.1f", limits.getAlertUpperLimit()));
|
||||||
|
limitThreshold[0] = Double.toString(limits.getAlertUpperLimit());
|
||||||
} else {
|
} else {
|
||||||
lim.append("undef");
|
lim.append("undef");
|
||||||
|
limitThreshold[0] = "-";
|
||||||
}
|
}
|
||||||
lim.append("/");
|
lim.append("/");
|
||||||
if (limits.getAlarmUpperLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
if (limits.getAlarmUpperLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
||||||
lim.append(String.format("%.1f", limits.getAlarmUpperLimit()));
|
lim.append(String.format("%.1f", limits.getAlarmUpperLimit()));
|
||||||
|
limitThreshold[1] = Double.toString(limits.getAlarmUpperLimit());
|
||||||
} else {
|
} else {
|
||||||
lim.append("undef");
|
lim.append("undef");
|
||||||
|
limitThreshold[1] = "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
lim.append(" Lower limit Value=");
|
lim.append("; Lower ");
|
||||||
if (limits.getAlertLowerLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
if (limits.getAlertLowerLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
||||||
lim.append(String.format("%.1f", limits.getAlertLowerLimit()));
|
lim.append(String.format("%.1f", limits.getAlertLowerLimit()));
|
||||||
|
limitThreshold[2] = Double.toString(limits.getAlertLowerLimit());
|
||||||
} else {
|
} else {
|
||||||
lim.append("undef");
|
lim.append("undef");
|
||||||
|
limitThreshold[2] = "-";
|
||||||
}
|
}
|
||||||
lim.append("/");
|
lim.append("/");
|
||||||
if (limits.getAlarmLowerLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
if (limits.getAlarmLowerLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
||||||
lim.append(String.format("%.1f", limits.getAlarmLowerLimit()));
|
lim.append(String.format("%.1f", limits.getAlarmLowerLimit()));
|
||||||
|
limitThreshold[3] = Double.toString(limits.getAlarmLowerLimit());
|
||||||
} else {
|
} else {
|
||||||
lim.append("undef");
|
lim.append("undef");
|
||||||
|
limitThreshold[3] = "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
lim.append(" Diff limit Value=");
|
lim.append("; Chg ");
|
||||||
if (limits.getAlertDiffLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
|
||||||
lim.append(String.format("%.1f", limits.getAlertDiffLimit()));
|
|
||||||
} else {
|
|
||||||
lim.append("undef");
|
|
||||||
}
|
|
||||||
lim.append("/");
|
|
||||||
if (limits.getAlarmDiffLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
|
||||||
lim.append(String.format("%.1f", limits.getAlarmDiffLimit()));
|
|
||||||
} else {
|
|
||||||
lim.append("undef");
|
|
||||||
}
|
|
||||||
|
|
||||||
lim.append(" ROC=");
|
|
||||||
if (limits.getAlertRocLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
if (limits.getAlertRocLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
||||||
lim.append(String.format("%.1f", limits.getAlertRocLimit()));
|
lim.append(String.format("%.1f", limits.getAlertRocLimit()));
|
||||||
|
limitThreshold[4] = Double.toString(limits.getAlertRocLimit());
|
||||||
} else {
|
} else {
|
||||||
lim.append("undef");
|
lim.append("undef");
|
||||||
|
limitThreshold[4] = "-";
|
||||||
}
|
}
|
||||||
lim.append("/");
|
lim.append("/");
|
||||||
if (limits.getAlarmRocLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
if (limits.getAlarmRocLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
||||||
lim.append(String.format("%.1f", limits.getAlarmRocLimit()));
|
lim.append(String.format("%.1f", limits.getAlarmRocLimit()));
|
||||||
|
limitThreshold[5] = Double.toString(limits.getAlarmRocLimit());
|
||||||
} else {
|
} else {
|
||||||
lim.append("undef");
|
lim.append("undef");
|
||||||
|
limitThreshold[5] = "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lim.append("; ObsFcstDiff ");
|
||||||
|
if (limits.getAlertDiffLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
||||||
|
lim.append(String.format("%.1f", limits.getAlertDiffLimit()));
|
||||||
|
limitThreshold[6] = Double.toString(limits.getAlertDiffLimit());
|
||||||
|
} else {
|
||||||
|
lim.append("undef");
|
||||||
|
limitThreshold[6] = "-";
|
||||||
|
}
|
||||||
|
lim.append("/");
|
||||||
|
if (limits.getAlarmDiffLimit() != Constants.MISSING_VALUE_DOUBLE) {
|
||||||
|
lim.append(String.format("%.1f", limits.getAlarmDiffLimit()));
|
||||||
|
limitThreshold[7] = Double.toString(limits.getAlarmDiffLimit());
|
||||||
|
} else {
|
||||||
|
lim.append("undef");
|
||||||
|
limitThreshold[7] = "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (opt.getVerbose()) {
|
if (opt.getVerbose()) {
|
||||||
writeln(lim.toString());
|
writeln(lim.toString());
|
||||||
}
|
}
|
||||||
|
@ -954,6 +1094,7 @@ class ReportWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maxfsct = fcstvalues.first();
|
maxfsct = fcstvalues.first();
|
||||||
|
|
||||||
}
|
}
|
||||||
return fcstvalues.isEmpty() ? null : fcstvalues.first();
|
return fcstvalues.isEmpty() ? null : fcstvalues.first();
|
||||||
}
|
}
|
||||||
|
@ -968,6 +1109,7 @@ class ReportWriter {
|
||||||
*/
|
*/
|
||||||
private void updateDatabase(Alertalarmval aav) throws Exception {
|
private void updateDatabase(Alertalarmval aav) throws Exception {
|
||||||
String nowAnsi = TimeUtil.formatToSqlTimestamp(now);
|
String nowAnsi = TimeUtil.formatToSqlTimestamp(now);
|
||||||
|
String nowToAction = nowAnsi.substring(0, 19);
|
||||||
String validAnsi = TimeUtil.formatToSqlTimestamp(aav.getId()
|
String validAnsi = TimeUtil.formatToSqlTimestamp(aav.getId()
|
||||||
.getValidtime());
|
.getValidtime());
|
||||||
String basisAnsi = TimeUtil.formatToSqlTimestamp(aav.getId()
|
String basisAnsi = TimeUtil.formatToSqlTimestamp(aav.getId()
|
||||||
|
@ -975,7 +1117,7 @@ class ReportWriter {
|
||||||
|
|
||||||
StringBuilder query = new StringBuilder();
|
StringBuilder query = new StringBuilder();
|
||||||
query.append(" UPDATE alertalarmval SET action_time ='");
|
query.append(" UPDATE alertalarmval SET action_time ='");
|
||||||
query.append(nowAnsi + "' ");
|
query.append(nowToAction + "' ");
|
||||||
query.append("WHERE lid='" + aav.getId().getLid() + "' ");
|
query.append("WHERE lid='" + aav.getId().getLid() + "' ");
|
||||||
query.append("AND pe='" + aav.getId().getPe() + "' ");
|
query.append("AND pe='" + aav.getId().getPe() + "' ");
|
||||||
query.append("AND dur=" + aav.getId().getDur() + Constants.SPACE);
|
query.append("AND dur=" + aav.getId().getDur() + Constants.SPACE);
|
||||||
|
@ -1026,6 +1168,7 @@ class ReportWriter {
|
||||||
try {
|
try {
|
||||||
dao = new CoreDao(DaoConfig.forDatabase(opt.getDbname()));
|
dao = new CoreDao(DaoConfig.forDatabase(opt.getDbname()));
|
||||||
limData = dao.executeSQLQuery(query);
|
limData = dao.executeSQLQuery(query);
|
||||||
|
|
||||||
if (limData != null && limData.length > 0) {
|
if (limData != null && limData.length > 0) {
|
||||||
for (Object lr : limData) {
|
for (Object lr : limData) {
|
||||||
limRow = (Object[]) lr;
|
limRow = (Object[]) lr;
|
||||||
|
@ -1039,12 +1182,15 @@ class ReportWriter {
|
||||||
if (dateWithin) {
|
if (dateWithin) {
|
||||||
locRangeFound = true;
|
locRangeFound = true;
|
||||||
copyThresholds(limits, limRow, locRangeFound);
|
copyThresholds(limits, limRow, locRangeFound);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!locRangeFound) {
|
if (!locRangeFound) {
|
||||||
query = "SELECT * FROM datalimits WHERE pe='" + pe
|
query = "SELECT * FROM datalimits WHERE pe='" + pe
|
||||||
+ "' AND dur=" + dur;
|
+ "' AND dur=" + dur;
|
||||||
|
|
||||||
limData = dao.executeSQLQuery(query);
|
limData = dao.executeSQLQuery(query);
|
||||||
if (limData != null && limData.length > 0) {
|
if (limData != null && limData.length > 0) {
|
||||||
for (Object lr : limData) {
|
for (Object lr : limData) {
|
||||||
|
@ -1063,7 +1209,6 @@ class ReportWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
statusHandler.error("- PostgresSQL error executing Query = ["
|
statusHandler.error("- PostgresSQL error executing Query = ["
|
||||||
|
@ -1414,7 +1559,7 @@ class ReportWriter {
|
||||||
* @return - a shefpe row
|
* @return - a shefpe row
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private String getShefPeInfo(String pe) throws Exception {
|
private Shefpe getShefPeInfo(String pe) throws Exception {
|
||||||
Object[] peData = null;
|
Object[] peData = null;
|
||||||
CoreDao dao = null;
|
CoreDao dao = null;
|
||||||
Object[] peInfo = null;
|
Object[] peInfo = null;
|
||||||
|
@ -1433,11 +1578,21 @@ class ReportWriter {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peInfo == null) {
|
/*if (peInfo == null) {
|
||||||
return "UndefinedName";
|
return "UndefinedName";
|
||||||
|
}*/
|
||||||
|
|
||||||
|
Shefpe peRecord = new Shefpe();
|
||||||
|
|
||||||
|
if (peInfo != null) {
|
||||||
|
peRecord.setName((String) peInfo[1]);
|
||||||
|
peRecord.setEngUnit((String) peInfo[2]);
|
||||||
|
} else {
|
||||||
|
peRecord = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (String) peInfo[1];
|
|
||||||
|
return peRecord;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1473,12 +1628,102 @@ class ReportWriter {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query the riverstat table and obtain stream name for the given location id
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param pe
|
||||||
|
* - the location id
|
||||||
|
*
|
||||||
|
* @return - riverstat
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private Riverstat getRiverStatInfo(String lid) throws Exception {
|
||||||
|
Object[] rsData = null;
|
||||||
|
CoreDao dao = null;
|
||||||
|
Object[] rsInfo = null;
|
||||||
|
final String query = "SELECT * FROM riverstat WHERE lid='" + lid + "'";
|
||||||
|
try {
|
||||||
|
dao = new CoreDao(DaoConfig.forDatabase(opt.getDbname()));
|
||||||
|
rsData = dao.executeSQLQuery(query);
|
||||||
|
if (rsData != null && rsData.length > 0) {
|
||||||
|
rsInfo = (Object[]) rsData[0];
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
statusHandler
|
||||||
|
.error(" - PostgresSQL error retrieving stream name info for "
|
||||||
|
+ lid);
|
||||||
|
statusHandler.error("Query = [" + query + "]");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
Riverstat rsRecord = new Riverstat();
|
||||||
|
if (rsInfo != null) {
|
||||||
|
rsRecord.setStream((String) rsInfo[20]);
|
||||||
|
} else
|
||||||
|
rsRecord = null;
|
||||||
|
|
||||||
|
return rsRecord;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query the descrip table and obtain proximity field for the given location id
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param pe
|
||||||
|
* - the location id
|
||||||
|
*
|
||||||
|
* @return - descrip
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
|
||||||
|
private String getDescripInfo(String lid) throws Exception {
|
||||||
|
Object[] dcData = null;
|
||||||
|
CoreDao dao = null;
|
||||||
|
Object[] dcInfo = null;
|
||||||
|
String proximityStr = null;
|
||||||
|
final String query = "SELECT * FROM descrip WHERE lid='" + lid + "'";
|
||||||
|
try {
|
||||||
|
dao = new CoreDao(DaoConfig.forDatabase(opt.getDbname()));
|
||||||
|
dcData = dao.executeSQLQuery(query);
|
||||||
|
if (dcData != null && dcData.length > 0) {
|
||||||
|
statusHandler.debug("In getDescriptionInfo1 - query is select * from descript where lid is " + lid);
|
||||||
|
dcInfo = (Object[]) dcData[0];
|
||||||
|
if (dcInfo == null)
|
||||||
|
{
|
||||||
|
proximityStr = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proximityStr = (String) dcInfo[5] + Constants.SPACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
statusHandler
|
||||||
|
.error(" - PostgresSQL error retrieving descrip info for "
|
||||||
|
+ lid);
|
||||||
|
statusHandler.error("Query = [" + query + "]");
|
||||||
|
throw e;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return proximityStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return - the alarm count
|
* @return - the alarm count
|
||||||
*/
|
*/
|
||||||
public int getAlarmCount() {
|
public int getAlarmCount() {
|
||||||
return alarmCount;
|
return alarmCount;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return threshold
|
||||||
|
*/
|
||||||
|
public String getLimitThreshold() {
|
||||||
|
return limitThreshold.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* does not perform disk access
|
* does not perform disk access
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
* DATE PROGRAMMER DESCRIPTION/REASON
|
* DATE PROGRAMMER DESCRIPTION/REASON
|
||||||
* 9/15/2006 P Tilles added lid to structure gage_radar_pair_struct
|
* 9/15/2006 P Tilles added lid to structure gage_radar_pair_struct
|
||||||
* August 2008 P Tilles added arrays for Q2
|
* August 2008 P Tilles added arrays for Q2
|
||||||
*
|
* 12/12/2014 C Gobs added include "DAARadar.h"
|
||||||
********************************************************************************
|
********************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
||||||
#include "get_os_system.h"
|
#include "get_os_system.h"
|
||||||
#include "convert_hrap.h" /* Hrap to LatLon Conversion utilities */
|
#include "convert_hrap.h" /* Hrap to LatLon Conversion utilities */
|
||||||
#include "time_convert.h"
|
#include "time_convert.h"
|
||||||
|
#include "DAARadar.h"
|
||||||
#include "HourlyPC.h"
|
#include "HourlyPC.h"
|
||||||
#include "mpe_write_xmrg.h"
|
#include "mpe_write_xmrg.h"
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,18 @@
|
||||||
********************************************************************************
|
********************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* * SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* May 2014 ptilles Initial creation/ checkin for 14.3.1
|
||||||
|
* Dec 12, 2014 16804 cgobs Fix problems with NULL Products' being considered missing, when certain null products
|
||||||
|
* should be considered all zero fields. (RM 16804 = DIM 17655)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mpe_fieldgen.h"
|
#include "mpe_fieldgen.h"
|
||||||
#define ACC_MIN 0.01
|
#define ACC_MIN 0.01
|
||||||
|
|
||||||
|
@ -149,7 +161,7 @@ void readRDMosaicRadars(const char * radarID,
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
int haveUsefulDAARadar(const char * radarID, const char * datetime, const int daa_wind,
|
int haveUsefulDAARadar(const char * radarId, const char * datetime, const int daa_wind,
|
||||||
const int minCoverageDur, float radar [ ] [ NUM_DPA_COLS ] ,
|
const int minCoverageDur, float radar [ ] [ NUM_DPA_COLS ] ,
|
||||||
int * radarAvailFlag)
|
int * radarAvailFlag)
|
||||||
|
|
||||||
|
@ -163,13 +175,13 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
|
||||||
double bias, xmax ;
|
double bias, xmax ;
|
||||||
long int irc = 0 ;
|
long int irc = 0 ;
|
||||||
|
|
||||||
readDAARadar(radarID, datetime, daa_wind, &xmax, &bias, fname, &itim,
|
readDAARadar(radarId, datetime, daa_wind, &xmax, &bias, fname, &itim,
|
||||||
&coverageDur, &nullProductFlag, &irc) ;
|
&coverageDur, &nullProductFlag, &irc) ;
|
||||||
|
|
||||||
if(irc == 0) //DAA is available
|
if(irc == 0) //DAA is available
|
||||||
{
|
{
|
||||||
|
|
||||||
sprintf ( message , "DAA product found for radar = %s\n", radarID) ;
|
sprintf ( message , "DAA product found for radar = %s\n", radarId) ;
|
||||||
printMessage(message, logFile);
|
printMessage(message, logFile);
|
||||||
|
|
||||||
*radarAvailFlag = 1 ;
|
*radarAvailFlag = 1 ;
|
||||||
|
@ -197,14 +209,18 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
|
||||||
printMessage(message, logFile);
|
printMessage(message, logFile);
|
||||||
|
|
||||||
read_daa_decoded(fname, &len, radar, &ierr) ;
|
read_daa_decoded(fname, &len, radar, &ierr) ;
|
||||||
|
|
||||||
if(ierr != 0)
|
if(ierr != 0)
|
||||||
{
|
{
|
||||||
/*-------------------------------------------------------*/
|
/*-------------------------------------------------------*/
|
||||||
/* error reading DAA product - missing data substituted */
|
/* error reading DAA product - missing data substituted */
|
||||||
/*-------------------------------------------------------*/
|
/*-------------------------------------------------------*/
|
||||||
|
|
||||||
sprintf ( message , "ERROR: #%d encountered reading radar file = %s"
|
sprintf ( message , "ERROR: #%d encountered reading radar file = %s"
|
||||||
" -- missing data substituted.", ierr, fname ) ;
|
" -- missing data substituted.", ierr, fname ) ;
|
||||||
printMessage(message, logFile);
|
printMessage(message, logFile);
|
||||||
|
|
||||||
|
haveGoodRadarProduct = 0;
|
||||||
*radarAvailFlag = 0 ;
|
*radarAvailFlag = 0 ;
|
||||||
|
|
||||||
for( i = 0; i < NUM_DPA_COLS; i++)
|
for( i = 0; i < NUM_DPA_COLS; i++)
|
||||||
|
@ -212,27 +228,34 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
|
||||||
for( j = 0; j < NUM_DPA_COLS; j++)
|
for( j = 0; j < NUM_DPA_COLS; j++)
|
||||||
radar[i][j] = RADAR_DEFAULT ;
|
radar[i][j] = RADAR_DEFAULT ;
|
||||||
}
|
}
|
||||||
|
|
||||||
haveGoodRadarProduct = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else //good product
|
|
||||||
|
else //ierr == 0, which means it is a good product
|
||||||
{
|
{
|
||||||
haveGoodRadarProduct = 1;
|
haveGoodRadarProduct = 1;
|
||||||
*radarAvailFlag = 1 ;
|
*radarAvailFlag = 1 ;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else //this is a null product
|
} // end if (nullProductFlag == 0)
|
||||||
|
|
||||||
|
else //is a null product of some kind
|
||||||
{
|
{
|
||||||
|
|
||||||
//consider it enough info to say it is 0.0
|
/*--------------------------------*/
|
||||||
if(nullProductFlag == 5 && coverageDur >= minCoverageDur)
|
/* null product processing */
|
||||||
/*-----------------------------------------------------------------------------------------*/
|
/*--------------------------------*/
|
||||||
/* if null_product_flag = 5 and coverageDur >= min_coverage_dur then set field to all 0.0 */
|
|
||||||
/*-----------------------------------------------------------------------------------------*/
|
if(nullProductFlag == 5)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if(coverageDur >= minCoverageDur)
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------------*/
|
||||||
|
/* if coverageDur >= min_coverage_dur then set field to all 0.0 */
|
||||||
|
/*-----------------------------------------------------------------------------------------*/
|
||||||
haveGoodRadarProduct = 1;
|
haveGoodRadarProduct = 1;
|
||||||
*radarAvailFlag = 2 ;
|
*radarAvailFlag = 2 ;
|
||||||
|
|
||||||
sprintf ( message , "null product flag = 5 and coverage > min coverage -- all 0.0 field substituted.");
|
sprintf ( message , "null product flag = 5 and coverage > min coverage -- all 0.0 field substituted.");
|
||||||
printMessage(message, logFile);
|
printMessage(message, logFile);
|
||||||
|
|
||||||
|
@ -240,9 +263,52 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
|
||||||
{
|
{
|
||||||
for( j = 0; j < NUM_DPA_COLS; j++)
|
for( j = 0; j < NUM_DPA_COLS; j++)
|
||||||
radar[i][j] = 0.0 ;
|
radar[i][j] = 0.0 ;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //consider it missing
|
|
||||||
|
else //coverageDur < minCoverageDur
|
||||||
|
{
|
||||||
|
if(isPrevHourNullProdFlag5(radarId, datetime, daa_wind))
|
||||||
|
{
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
/* read DAARadar record for previous hour */
|
||||||
|
/* if the product for the previous hour also has null_product_flag = 5, */
|
||||||
|
/* then set field to all 0.0 */
|
||||||
|
/*-------------------------------------------------------------------------------*/
|
||||||
|
haveGoodRadarProduct = 1;
|
||||||
|
*radarAvailFlag = 2 ;
|
||||||
|
sprintf ( message , "null product flag = 5 for current and previous products -- all 0.0 field substituted.");
|
||||||
|
printMessage(message, logFile);
|
||||||
|
|
||||||
|
for( i = 0; i < NUM_DPA_COLS; i++)
|
||||||
|
{
|
||||||
|
for( j = 0; j < NUM_DPA_COLS; j++)
|
||||||
|
radar[i][j] = 0.0 ;
|
||||||
|
} //end for i
|
||||||
|
}
|
||||||
|
|
||||||
|
else //not isPrevHourNullProdFlag5
|
||||||
|
{
|
||||||
|
|
||||||
|
haveGoodRadarProduct = 0;
|
||||||
|
*radarAvailFlag = 0 ;
|
||||||
|
|
||||||
|
sprintf ( message , "unacceptable null product with coverage < min coverage or unspecified -- all missing field substituted.");
|
||||||
|
printMessage(message, logFile);
|
||||||
|
|
||||||
|
for( i = 0; i < NUM_DPA_COLS; i++)
|
||||||
|
{
|
||||||
|
for( j = 0; j < NUM_DPA_COLS; j++)
|
||||||
|
radar[i][j] = RADAR_DEFAULT ;
|
||||||
|
}
|
||||||
|
|
||||||
|
} //end else not isPrevHourNullProdFlag5
|
||||||
|
} //end else coverageDur < minCoverageDur
|
||||||
|
} //end if (nullProductFlag == 5)
|
||||||
|
|
||||||
|
|
||||||
|
else //does not have a null product flag == 5, so consider it missing
|
||||||
{
|
{
|
||||||
|
|
||||||
haveGoodRadarProduct = 0;
|
haveGoodRadarProduct = 0;
|
||||||
|
@ -255,19 +321,50 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
|
||||||
for( j = 0; j < NUM_DPA_COLS; j++)
|
for( j = 0; j < NUM_DPA_COLS; j++)
|
||||||
radar[i][j] = RADAR_DEFAULT ;
|
radar[i][j] = RADAR_DEFAULT ;
|
||||||
}
|
}
|
||||||
}
|
} //end else consider it missing
|
||||||
} //end if null product
|
} //end else is a null product of some kind
|
||||||
|
|
||||||
|
} //end if (irc == 0) -> good read of DAA product
|
||||||
|
|
||||||
|
else //not able to read DAA product
|
||||||
|
{
|
||||||
|
|
||||||
|
if( isMissingHourCoveredByNullProduct(radarId, datetime, daa_wind))
|
||||||
|
{
|
||||||
|
haveGoodRadarProduct = 1;
|
||||||
|
*radarAvailFlag = 2 ;
|
||||||
|
|
||||||
|
for( i = 0; i < NUM_DPA_COLS; i++)
|
||||||
|
{
|
||||||
|
for( j = 0; j < NUM_DPA_COLS; j++)
|
||||||
|
radar[i][j] = 0.0 ;
|
||||||
|
} //end for i
|
||||||
|
|
||||||
|
sprintf ( message , "haveUsefulDAARadar(): missing hour covered by later hour null product -- all zero field used. ");
|
||||||
|
printMessage(message, logFile);
|
||||||
|
|
||||||
}
|
}
|
||||||
else //error reading DAA product
|
|
||||||
|
else
|
||||||
{
|
{
|
||||||
haveGoodRadarProduct = 0;
|
haveGoodRadarProduct = 0;
|
||||||
*radarAvailFlag = 0 ;
|
*radarAvailFlag = 0 ;
|
||||||
|
|
||||||
|
sprintf ( message , "haveUsefulDAARadar(): data for hour not available -- all missing field used. ");
|
||||||
|
printMessage(message, logFile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
sprintf ( message , "leaving haveUsefulDAARadar(): haveGoodRadarProduct = %d and *radarAvailFlag = %d",
|
||||||
|
haveGoodRadarProduct, *radarAvailFlag);
|
||||||
|
printMessage(message, logFile);
|
||||||
|
|
||||||
|
*/
|
||||||
return haveGoodRadarProduct;
|
return haveGoodRadarProduct;
|
||||||
|
|
||||||
}
|
} //end haveUsefulDAARadar()
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------
|
||||||
int haveUsefulDPARadar(const char * radarID, const char * datetime, const int dpa_wind,
|
int haveUsefulDPARadar(const char * radarID, const char * datetime, const int dpa_wind,
|
||||||
|
@ -356,7 +453,6 @@ int haveUsefulDPARadar(const char * radarID, const char * datetime, const int dp
|
||||||
else //zero product
|
else //zero product
|
||||||
{
|
{
|
||||||
haveGoodRadarProduct = 1;
|
haveGoodRadarProduct = 1;
|
||||||
|
|
||||||
*radarAvailFlag = 2 ;
|
*radarAvailFlag = 2 ;
|
||||||
|
|
||||||
sprintf ( message , "STATUS: radar data all zero for current hour.") ;
|
sprintf ( message , "STATUS: radar data all zero for current hour.") ;
|
||||||
|
@ -380,9 +476,300 @@ int haveUsefulDPARadar(const char * radarID, const char * datetime, const int dp
|
||||||
|
|
||||||
return haveGoodRadarProduct;
|
return haveGoodRadarProduct;
|
||||||
|
|
||||||
/* ============== Statements containing RCS keywords: */
|
} //end haveUsefulDPARadar()
|
||||||
{static char rcs_id1[] = "$Source: /fs/hseb/ob9e/ohd/pproc_lib/src/MPEFieldGen/RCS/readRDMosaicRadars.c,v $";
|
|
||||||
static char rcs_id2[] = "$Id: readRDMosaicRadars.c,v 1.4 2012/09/10 19:38:47 pst Exp $";}
|
|
||||||
/* =================================================== */
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int isPrevHourNullProdFlag5(const char * radarId,
|
||||||
|
const char * datetime,
|
||||||
|
const int daawind
|
||||||
|
)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
this function searches the DAARadar table for a record for the previous hour
|
||||||
|
|
||||||
|
if no such top-of-hour record is found, then a search is done on either side
|
||||||
|
of the hour up to idaawind minutes to look for a record
|
||||||
|
|
||||||
|
if no record is found within the window, then return 0 (false)
|
||||||
|
|
||||||
|
if a record is found, then the value of the nullproductflag is checked
|
||||||
|
if nullproductflag = 5, then return 1 (true)
|
||||||
|
else return 0 (false)
|
||||||
|
|
||||||
|
calling subroutine: readRDMosaicRadars
|
||||||
|
*/
|
||||||
|
|
||||||
|
int found = 0;
|
||||||
|
int result = 0;
|
||||||
|
int minOff = 0;
|
||||||
|
int nullProductFlag;
|
||||||
|
|
||||||
|
char where [ 256 ];
|
||||||
|
DAARadar * pDAARadarHead = NULL ;
|
||||||
|
char queryObsTime[ANSI_TIME_LEN + 1];
|
||||||
|
|
||||||
|
time_t currentHourObsTime = 0;
|
||||||
|
time_t previousHourObsTime = 0;
|
||||||
|
|
||||||
|
time_t beforeTOHObsTime = 0;
|
||||||
|
time_t afterTOHObsTime = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// memset (radarId, '\0',RADAR_ID_LEN + 1 );
|
||||||
|
// strncpy (radarId, radar, RADAR_ID_LEN );
|
||||||
|
|
||||||
|
/*
|
||||||
|
sprintf ( message , "radar id = %s obstime = %s daa_wind = %d.\n", rrad, str, idaawind);
|
||||||
|
printMessage(message, logFile);
|
||||||
|
*/
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* subtract 1 hour from obstime */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
yearsec_ansi_to_timet(datetime, ¤tHourObsTime);
|
||||||
|
|
||||||
|
previousHourObsTime = currentHourObsTime - SECONDS_PER_HOUR;
|
||||||
|
|
||||||
|
timet_to_yearsec_ansi(previousHourObsTime, queryObsTime);
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* search for top-of-hour record from previous hour */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
sprintf ( where , "WHERE radid='%s' AND obstime='%s' ",
|
||||||
|
radarId, queryObsTime ) ;
|
||||||
|
|
||||||
|
pDAARadarHead = GetDAARadar ( where );
|
||||||
|
|
||||||
|
if ( pDAARadarHead != NULL )
|
||||||
|
{
|
||||||
|
/* A top-of-hour record from previous hour has been found. */
|
||||||
|
nullProductFlag = pDAARadarHead->null_product_flag;
|
||||||
|
found = 1;
|
||||||
|
|
||||||
|
FreeDAARadar ( pDAARadarHead );
|
||||||
|
pDAARadarHead = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Search for non-top-of-hour record.
|
||||||
|
If searching in window around 00z, then need to use date
|
||||||
|
of previous day. */
|
||||||
|
|
||||||
|
for ( minOff = 1; minOff < daawind + 1; minOff ++)
|
||||||
|
{
|
||||||
|
/* check after TOH */
|
||||||
|
|
||||||
|
afterTOHObsTime = previousHourObsTime + (minOff * SECONDS_PER_MINUTE);
|
||||||
|
timet_to_yearsec_ansi(afterTOHObsTime, queryObsTime);
|
||||||
|
|
||||||
|
sprintf ( where , "WHERE radid='%s' AND obstime='%s' ",
|
||||||
|
radarId, queryObsTime ) ;
|
||||||
|
|
||||||
|
pDAARadarHead = GetDAARadar ( where );
|
||||||
|
|
||||||
|
if ( pDAARadarHead != NULL )
|
||||||
|
{
|
||||||
|
/* A record has been found. */
|
||||||
|
nullProductFlag = pDAARadarHead->null_product_flag;
|
||||||
|
found = 1;
|
||||||
|
|
||||||
|
FreeDAARadar ( pDAARadarHead );
|
||||||
|
pDAARadarHead = NULL;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check before TOH */
|
||||||
|
|
||||||
|
beforeTOHObsTime = previousHourObsTime - (minOff * SECONDS_PER_MINUTE);
|
||||||
|
timet_to_yearsec_ansi(beforeTOHObsTime, queryObsTime);
|
||||||
|
|
||||||
|
sprintf ( where , "WHERE radid='%s' AND obstime='%s' ",
|
||||||
|
radarId, queryObsTime ) ;
|
||||||
|
|
||||||
|
pDAARadarHead = GetDAARadar ( where );
|
||||||
|
|
||||||
|
if ( pDAARadarHead != NULL )
|
||||||
|
{
|
||||||
|
/* A record has been found. */
|
||||||
|
nullProductFlag = pDAARadarHead->null_product_flag;
|
||||||
|
found = 1 ;
|
||||||
|
|
||||||
|
FreeDAARadar ( pDAARadarHead );
|
||||||
|
pDAARadarHead = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} //end for minOff
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
if ( ( found == 1 ) && (nullProductFlag == 5))
|
||||||
|
{
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( pDAARadarHead != NULL )
|
||||||
|
{
|
||||||
|
FreeDAARadar ( pDAARadarHead );
|
||||||
|
pDAARadarHead = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} //end isPrevHourNullProdFlag5
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
int isMissingHourCoveredByNullProduct(const char * radarId,
|
||||||
|
const char * datetimeString,
|
||||||
|
const int daawind)
|
||||||
|
{
|
||||||
|
|
||||||
|
// This function determines if a null product for the next hour is available that indicates that there was no precip
|
||||||
|
// during the period for which the product in question was missing
|
||||||
|
|
||||||
|
int covered = 0;
|
||||||
|
int minOff = 0;
|
||||||
|
int nullProductFlag = 0;
|
||||||
|
int coverageDur = 0;
|
||||||
|
char where [ 256 ];
|
||||||
|
DAARadar * pDAARadarHead = NULL ;
|
||||||
|
|
||||||
|
char queryObsTime[ANSI_TIME_LEN + 1];
|
||||||
|
|
||||||
|
time_t currentHourObsTime = 0;
|
||||||
|
time_t nextHourObsTime = 0;
|
||||||
|
|
||||||
|
time_t beforeTOHObsTime = 0;
|
||||||
|
time_t afterTOHObsTime = 0;
|
||||||
|
|
||||||
|
// memset ( radarId,'\0',RADAR_ID_LEN + 1 );
|
||||||
|
// strncpy (radarId,rad, RADAR_ID_LEN );
|
||||||
|
|
||||||
|
/*
|
||||||
|
sprintf ( message , "radar id = %s obstime = %s daa_wind = %d.\n", rrad, str, idaawind);
|
||||||
|
printMessage(message, logFile);
|
||||||
|
*/
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* add 1 hour to obstime */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
yearsec_ansi_to_timet(datetimeString, ¤tHourObsTime);
|
||||||
|
|
||||||
|
nextHourObsTime = currentHourObsTime + SECONDS_PER_HOUR;
|
||||||
|
|
||||||
|
timet_to_yearsec_ansi(nextHourObsTime, queryObsTime);
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* search for top-of-hour record from previous hour */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
sprintf ( where , "WHERE radid='%s' AND obstime='%s' ",
|
||||||
|
radarId, queryObsTime ) ;
|
||||||
|
|
||||||
|
pDAARadarHead = GetDAARadar ( where );
|
||||||
|
|
||||||
|
if ( pDAARadarHead != NULL )
|
||||||
|
{
|
||||||
|
/* A top-of-hour record from next hour has been found. */
|
||||||
|
|
||||||
|
covered = isCovered(pDAARadarHead, currentHourObsTime);
|
||||||
|
FreeDAARadar ( pDAARadarHead );
|
||||||
|
pDAARadarHead = NULL;
|
||||||
|
}
|
||||||
|
else //there is no record exactly at the top of the hour
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
for ( minOff = 1; minOff < daawind + 1; minOff ++)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* check after TOH */
|
||||||
|
|
||||||
|
afterTOHObsTime = nextHourObsTime + (minOff * SECONDS_PER_MINUTE);
|
||||||
|
timet_to_yearsec_ansi(afterTOHObsTime, queryObsTime);
|
||||||
|
|
||||||
|
|
||||||
|
sprintf ( where , "WHERE radid='%s' AND obstime='%s' ",
|
||||||
|
radarId, queryObsTime ) ;
|
||||||
|
|
||||||
|
|
||||||
|
sprintf ( message , " after TOH: WHERE clause = :%s:", where);
|
||||||
|
|
||||||
|
printMessage(message, logFile);
|
||||||
|
|
||||||
|
|
||||||
|
pDAARadarHead = GetDAARadar ( where );
|
||||||
|
|
||||||
|
if ( pDAARadarHead != NULL )
|
||||||
|
{
|
||||||
|
covered = isCovered(pDAARadarHead, currentHourObsTime);
|
||||||
|
FreeDAARadar ( pDAARadarHead );
|
||||||
|
pDAARadarHead = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check before TOH */
|
||||||
|
|
||||||
|
beforeTOHObsTime = nextHourObsTime - (minOff * SECONDS_PER_MINUTE);
|
||||||
|
timet_to_yearsec_ansi(beforeTOHObsTime, queryObsTime);
|
||||||
|
|
||||||
|
sprintf ( where , "WHERE radid='%s' AND obstime='%s' ",
|
||||||
|
radarId, queryObsTime ) ;
|
||||||
|
|
||||||
|
|
||||||
|
sprintf ( message , " before TOH: WHERE clause = :%s:", where);
|
||||||
|
|
||||||
|
printMessage(message, logFile);
|
||||||
|
|
||||||
|
pDAARadarHead = GetDAARadar ( where );
|
||||||
|
|
||||||
|
if ( pDAARadarHead != NULL )
|
||||||
|
{
|
||||||
|
covered = isCovered(pDAARadarHead, currentHourObsTime);
|
||||||
|
FreeDAARadar ( pDAARadarHead );
|
||||||
|
pDAARadarHead = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} //end for minutes
|
||||||
|
} //end else no record at exactly TOH
|
||||||
|
/*-----------------------------------------------------------------*/
|
||||||
|
|
||||||
|
return covered;
|
||||||
|
|
||||||
|
} //end isMissingHourCoveredByNullProduct
|
||||||
|
|
||||||
|
|
||||||
|
int isCovered(DAARadar *pDAARadar, time_t originalObsTime)
|
||||||
|
{
|
||||||
|
int covered = 0;
|
||||||
|
|
||||||
|
if (pDAARadar != NULL)
|
||||||
|
{
|
||||||
|
|
||||||
|
int nullProductFlag = pDAARadar->null_product_flag;
|
||||||
|
int coverageDurInMinutes = pDAARadar->coverage_dur;
|
||||||
|
|
||||||
|
|
||||||
|
if ((nullProductFlag == 5) && (coverageDurInMinutes > 0))
|
||||||
|
{
|
||||||
|
|
||||||
|
int obstime = pDAARadar->obstime;
|
||||||
|
|
||||||
|
int secondsSinceRain = coverageDurInMinutes * SECONDS_PER_MINUTE;
|
||||||
|
|
||||||
|
time_t noRainSinceTime = obstime - secondsSinceRain;
|
||||||
|
|
||||||
|
if (noRainSinceTime <= originalObsTime)
|
||||||
|
{
|
||||||
|
covered = 1; //True
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return covered;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue