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 [formerly 0bc501bd4c [formerly d53c809149da23fcae51138cc45c57aecd641794]]
Former-commit-id: a757b55446
Former-commit-id: 6cf71bae0e
This commit is contained in:
Shawn.Hooper 2015-01-22 16:05:41 -05:00
commit 953b71a3f8
6 changed files with 1255 additions and 372 deletions

View file

@ -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,7 +111,9 @@ 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>
* *
* @author mschenke * @author mschenke
@ -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;
@ -530,34 +560,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() {
loadColorData(
"PRECIP_ACCUM",//color value use
1, //duration in hours
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 {
// Convert display to data, cast to int, convert back to display
entry.setDisplayValue(dataToDisplay.convert((int) displayToData
.convert(threshold)));
}
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;
} }
private void loadColors() {
MPEFieldResource displayedResource = displayMgr
.getDisplayedFieldResource();
if (displayedResource != null) {
parameters = displayedResource.getCapability(
ColorMapCapability.class).getColorMapParameters();
} else {
DisplayFieldData displayedData = displayMgr.getDisplayFieldType();
parameters = MPEDisplayManager
.createColorMap(displayedData.getCv_use(), displayedData
.getCv_duration(), MPEFieldResourceData
.getDataUnitsForField(displayedData),
MPEFieldResourceData
.getDisplayUnitsForField(displayedData));
}
}
/** /**
* 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();
} }
} }

View file

@ -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:
# #

View file

@ -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
@ -63,8 +63,7 @@ class AlertalarmRecord {
groups = new HashMap<String, List<Alertalarmval>>(); groups = new HashMap<String, List<Alertalarmval>>();
} }
public static AlertalarmRecord newInstance() { public static AlertalarmRecord newInstance() {
if (instance == null)
instance = new AlertalarmRecord(); instance = new AlertalarmRecord();
return instance; return instance;
} }

View file

@ -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,84 +162,9 @@ 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());
writeNewline();
// 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();
// note which class of data is being considered via the filter
write("DATA FILTER: ");
EnumSet<FilterOption> flags = opt.getFilter();
if (CollectionUtil.isNullOrEmpty(flags)) {
writeln("All alerts/alarms considered (i.e. no filter).");
} else {
write("Only considering ");
if (flags.contains(FilterOption.OBSERVED)
&& !flags.contains(FilterOption.FORECAST)) {
write(FilterOption.OBSERVED.name().toLowerCase());
} else if (!flags.contains(FilterOption.OBSERVED)
&& flags.contains(FilterOption.FORECAST)) {
write(FilterOption.FORECAST.name().toLowerCase());
}
if (flags.contains(FilterOption.RATE_OF_CHANGE)) {
write(" " + FilterOption.RATE_OF_CHANGE.name().toLowerCase());
}
if (flags.contains(FilterOption.UPPER_LIMIT)) {
write(" " + FilterOption.UPPER_LIMIT.name().toLowerCase());
}
if (flags.contains(FilterOption.LOWER_LIMIT)) {
write(" " + FilterOption.LOWER_LIMIT.name().toLowerCase());
}
if (flags.contains(FilterOption.DIFF_LIMIT)) {
write(" " + FilterOption.DIFF_LIMIT.name().toLowerCase());
}
if (flags.contains(FilterOption.ALERTS)
&& !flags.contains(FilterOption.ALARMS)) {
write(" " + FilterOption.ALERTS.name().toLowerCase());
} else if (!flags.contains(FilterOption.ALERTS)
&& flags.contains(FilterOption.ALARMS)) {
write(" " + FilterOption.ALARMS.name().toLowerCase());
} else {
write(" " + FilterOption.ALERTS.name().toLowerCase() + " and "
+ FilterOption.ALARMS.name().toLowerCase());
}
writeNewline();
}
write("PE FILTER : ");
if (opt.getPEfilter() == null) {
writeln(" All Physical Elements are considered (i.e. no filter).");
} else {
write(" Only considering ");
writeln(opt.getPEfilter() + " physical element data");
}
if (opt.getMode() == ReportMode.RECENT
|| opt.getMode() == ReportMode.NEAR_NOW
|| opt.getMode() == ReportMode.FRESH
|| opt.getMode() == ReportMode.NEW_OR_INCREASED) {
write("NUM MINUTES: " + opt.getMinutes());
}
writeNewline();
writeln("--------------------------------------------------------------------");
} }
private void writeReportTrailer() { private void writeReportTrailer() {
@ -268,6 +204,71 @@ class ReportWriter {
+ reportMode + " MODE)"); + reportMode + " MODE)");
} }
writeln("\n-------------------------------------------------------------------"); writeln("\n-------------------------------------------------------------------");
/* add to match A1 format*/
write("DATA FILTER: ");
EnumSet<FilterOption> flags = opt.getFilter();
if (CollectionUtil.isNullOrEmpty(flags)) {
writeln("All alerts/alarms considered (i.e. no filter).");
} else {
write("Only considering ");
if (flags.contains(FilterOption.OBSERVED)
&& !flags.contains(FilterOption.FORECAST)) {
write(FilterOption.OBSERVED.name().toLowerCase());
} else if (!flags.contains(FilterOption.OBSERVED)
&& flags.contains(FilterOption.FORECAST)) {
write(FilterOption.FORECAST.name().toLowerCase());
}
if (flags.contains(FilterOption.RATE_OF_CHANGE)) {
write(" " + FilterOption.RATE_OF_CHANGE.name().toLowerCase());
}
if (flags.contains(FilterOption.UPPER_LIMIT)) {
write(" " + FilterOption.UPPER_LIMIT.name().toLowerCase());
}
if (flags.contains(FilterOption.LOWER_LIMIT)) {
write(" " + FilterOption.LOWER_LIMIT.name().toLowerCase());
}
if (flags.contains(FilterOption.DIFF_LIMIT)) {
write(" " + FilterOption.DIFF_LIMIT.name().toLowerCase());
}
if (flags.contains(FilterOption.ALERTS)
&& !flags.contains(FilterOption.ALARMS)) {
write(" " + FilterOption.ALERTS.name().toLowerCase());
} else if (!flags.contains(FilterOption.ALERTS)
&& flags.contains(FilterOption.ALARMS)) {
write(" " + FilterOption.ALARMS.name().toLowerCase());
} else {
write(" " + FilterOption.ALERTS.name().toLowerCase() + " and "
+ FilterOption.ALARMS.name().toLowerCase());
}
writeNewline();
}
write("PE FILTER : ");
if (opt.getPEfilter() == null) {
writeln(" All Physical Elements are considered (i.e. no filter).");
} else {
write(" Only considering ");
writeln(opt.getPEfilter() + " physical element data");
}
if (opt.getMode() == ReportMode.RECENT
|| opt.getMode() == ReportMode.NEAR_NOW
|| opt.getMode() == ReportMode.FRESH
|| opt.getMode() == ReportMode.NEW_OR_INCREASED) {
write("NUM MINUTES: " + opt.getMinutes());
}
writeNewline();
writeln("--------------------------------------------------------------------");
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,15 +678,15 @@ 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())) {
return true; return true;
} else if (aav.getValue() > latestValue) { } else if (aav.getValue() > latestValue) {
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(aav.getId().getAaCheck()); args.add(tsInfo);
args.add(aav.getId().getAaCateg()); args.add(peInfo);
args.add(validInfo);
args.add(aav.getValue()); args.add(aav.getValue());
args.add(basisInfo); args.add(validInfo);
/* args.add(aav.getId().getAaCheck());
args.add(aav.getId().getAaCateg());*/
if (aav.getId().getAaCheck().equals(ShefConstants.UPPER_CHECKSTR)) { if (aav.getId().getAaCheck().equals(ShefConstants.UPPER_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[1]);
} else {
args.add(limitThreshold[0]);
}
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 {
args.add(limitThreshold[2]);
}
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 { } else {
fmtSpecifier = " %s > %s %s %7.1f (value = %7.1f) %s"; args.add(0,"Obs");
args.add(3, aav.getSupplValue()); 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,14 +1109,15 @@ 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()
.getBasistime()); .getBasistime());
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,27 +1182,29 @@ 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);
if (limData != null && limData.length > 0) { limData = dao.executeSQLQuery(query);
for (Object lr : limData) { if (limData != null && limData.length > 0) {
limRow = (Object[]) lr; for (Object lr : limData) {
String mds = (String) limRow[2]; limRow = (Object[]) lr;
String mde = (String) limRow[3]; String mds = (String) limRow[2];
limits = new Datalimits(); String mde = (String) limRow[3];
limitsId = new DatalimitsId(pe, dur, mds); limits = new Datalimits();
limits.setId(limitsId); limitsId = new DatalimitsId(pe, dur, mds);
flushDataLimitsObj(limits); limits.setId(limitsId);
dateWithin = checkDateRange(validtime, mds, mde); flushDataLimitsObj(limits);
if (dateWithin) { dateWithin = checkDateRange(validtime, mds, mde);
copyThresholds(limits, limRow, locRangeFound); if (dateWithin) {
break; copyThresholds(limits, limRow, locRangeFound);
} break;
} }
} }
} }
@ -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
@ -1527,4 +1772,4 @@ class ReportWriter {
} }
} }
} }

View file

@ -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"

View file

@ -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
@ -71,7 +83,7 @@ void readRDMosaicRadars(const char * radarID,
const int daa_wind, const int daa_wind,
const int minCoverageDur, const int minCoverageDur,
const int ignoreDPARadar, const int ignoreDPARadar,
const int ignoreDAARadar, const int ignoreDAARadar,
float radar [ ] [ NUM_DPA_COLS ] , float radar [ ] [ NUM_DPA_COLS ] ,
int * radarAvailFlag, int * radarAvailFlag,
short * daa_avail_flag) short * daa_avail_flag)
@ -120,14 +132,14 @@ void readRDMosaicRadars(const char * radarID,
else //try DPA else //try DPA
{ {
useDPA = (! ignoreDPARadar && haveUsefulDPARadar(radarID, datetime, dpa_wind, radar, radarAvailFlag)); useDPA = (! ignoreDPARadar && haveUsefulDPARadar(radarID, datetime, dpa_wind, radar, radarAvailFlag));
if ( ! useDPA ) if ( ! useDPA )
{ {
/*---------------------------*/ /*---------------------------*/
/* set radar to all missing */ /* set radar to all missing */
/*---------------------------*/ /*---------------------------*/
for( i = 0; i < NUM_DPA_COLS; i++) for( i = 0; i < NUM_DPA_COLS; i++)
{ {
for( j = 0; j < NUM_DPA_COLS; j++) for( j = 0; j < NUM_DPA_COLS; j++)
@ -135,45 +147,45 @@ void readRDMosaicRadars(const char * radarID,
radar[i][j] = RADAR_DEFAULT ; radar[i][j] = RADAR_DEFAULT ;
} }
} }
sprintf ( message , "STATUS: radar marked as missing .") ; sprintf ( message , "STATUS: radar marked as missing .") ;
printMessage(message, logFile); printMessage(message, logFile);
} }
} }
return; return;
} }
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
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)
{ {
char fname[FNAME_LEN] = "" ; char fname[FNAME_LEN] = "" ;
int i, j ; int i, j ;
int itim, coverageDur, nullProductFlag; int itim, coverageDur, nullProductFlag;
int len, ierr ; int len, ierr ;
int haveGoodRadarProduct = 0; int haveGoodRadarProduct = 0;
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 ;
if(itim != 0) if(itim != 0)
{ {
sprintf ( message , "STATUS: no top-of-hour product found -- %d, " sprintf ( message , "STATUS: no top-of-hour product found -- %d, "
@ -185,204 +197,579 @@ int haveUsefulDAARadar(const char * radarID, const char * datetime, const int da
ierr = 0 ; ierr = 0 ;
/*---------------------------------------*/ /*---------------------------------------*/
/* check if product is a null product */ /* check if product is a null product */
/*---------------------------------------*/ /*---------------------------------------*/
if(nullProductFlag == 0) //not a null product if(nullProductFlag == 0) //not a null product
{ {
sprintf ( message , "Maximum radar value = %7.2f mm", xmax ) ; sprintf ( message , "Maximum radar value = %7.2f mm", xmax ) ;
printMessage(message, logFile); printMessage(message, logFile);
sprintf ( message , "reading DAA decoded product with filename = %s\n", fname); sprintf ( message , "reading DAA decoded product with filename = %s\n", fname);
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);
*radarAvailFlag = 0 ;
haveGoodRadarProduct = 0;
*radarAvailFlag = 0 ;
for( i = 0; i < NUM_DPA_COLS; i++) for( i = 0; i < NUM_DPA_COLS; i++)
{ {
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
{
haveGoodRadarProduct = 1;
*radarAvailFlag = 1 ;
}
}
else //this is a null product
{
//consider it enough info to say it is 0.0 else //ierr == 0, which means it is a good product
if(nullProductFlag == 5 && coverageDur >= minCoverageDur) {
/*-----------------------------------------------------------------------------------------*/ haveGoodRadarProduct = 1;
/* if null_product_flag = 5 and coverageDur >= min_coverage_dur then set field to all 0.0 */ *radarAvailFlag = 1 ;
/*-----------------------------------------------------------------------------------------*/ }
{
haveGoodRadarProduct = 1; } // end if (nullProductFlag == 0)
*radarAvailFlag = 2 ;
sprintf ( message , "null product flag = 5 and coverage > min coverage -- all 0.0 field substituted."); else //is a null product of some kind
printMessage(message, logFile); {
for( i = 0; i < NUM_DPA_COLS; i++) /*--------------------------------*/
{ /* null product processing */
for( j = 0; j < NUM_DPA_COLS; j++) /*--------------------------------*/
radar[i][j] = 0.0 ;
}
}
else //consider it missing
{
haveGoodRadarProduct = 0; if(nullProductFlag == 5)
*radarAvailFlag = 0 ; {
sprintf ( message , "null product with coverage < min coverage or unspecified -- all missing field substituted.");
printMessage(message, logFile); if(coverageDur >= minCoverageDur)
{
/*-----------------------------------------------------------------------------------------*/
/* if coverageDur >= min_coverage_dur then set field to all 0.0 */
/*-----------------------------------------------------------------------------------------*/
haveGoodRadarProduct = 1;
*radarAvailFlag = 2 ;
sprintf ( message , "null product flag = 5 and coverage > min coverage -- 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 ;
}
}
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;
*radarAvailFlag = 0 ;
sprintf ( message , "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 consider it missing
} //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
{
haveGoodRadarProduct = 0;
*radarAvailFlag = 0 ;
sprintf ( message , "haveUsefulDAARadar(): data for hour not available -- all missing field used. ");
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 if null product
} }
else //error reading DAA product /*
{ sprintf ( message , "leaving haveUsefulDAARadar(): haveGoodRadarProduct = %d and *radarAvailFlag = %d",
haveGoodRadarProduct = 0; haveGoodRadarProduct, *radarAvailFlag);
*radarAvailFlag = 0 ; 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,
float radar [ ] [ NUM_DPA_COLS ] , int * radarAvailFlag) float radar [ ] [ NUM_DPA_COLS ] , int * radarAvailFlag)
{ {
char fname[FNAME_LEN] = "" ; char fname[FNAME_LEN] = "" ;
int i, j ; int i, j ;
int itim; int itim;
int len, ierr ; int len, ierr ;
int haveGoodRadarProduct = 0; int haveGoodRadarProduct = 0;
double bias, xmax ; double bias, xmax ;
long int irc = 0 ; long int irc = 0 ;
irc = 0; irc = 0;
readDPARadar(radarID, datetime, dpa_wind, &xmax, &bias, fname, &itim, &irc); readDPARadar(radarID, datetime, dpa_wind, &xmax, &bias, fname, &itim, &irc);
if(irc == 0) //should be a radar file available
{
sprintf ( message , "DPA product found for radar = %s\n", radarID) ;
printMessage(message, logFile);
}
if((irc != 0) || (xmax == -99.0)) // dpa radar
{
sprintf ( message , " no radar data for current hour" if(irc == 0) //should be a radar file available
" -- missing data substituted\n"); {
printMessage(message, logFile); sprintf ( message , "DPA product found for radar = %s\n", radarID) ;
printMessage(message, logFile);
}
if((irc != 0) || (xmax == -99.0)) // dpa radar
{
sprintf ( message , " no radar data for current hour"
" -- missing data substituted\n");
printMessage(message, logFile);
haveGoodRadarProduct = 0; haveGoodRadarProduct = 0;
} }
else //read DPA product else //read DPA product
{ {
/*-----------------------------------------*/ /*-----------------------------------------*/
/* xmax > 0.0 -- read decoded DPA product */ /* xmax > 0.0 -- read decoded DPA product */
/*-----------------------------------------*/ /*-----------------------------------------*/
if(xmax > 0.0) if(xmax > 0.0)
{ {
len = strlen(fname) ; len = strlen(fname) ;
ierr = 0 ; ierr = 0 ;
sprintf ( message , "Maximum radar value = %7.2f mm", xmax ) ; sprintf ( message , "Maximum radar value = %7.2f mm", xmax ) ;
printMessage(message, logFile); printMessage(message, logFile);
read_stage1_decoded_(fname, &len, radar, &ierr) ; read_stage1_decoded_(fname, &len, radar, &ierr) ;
if(ierr != 0) if(ierr != 0)
{ {
haveGoodRadarProduct = 0; haveGoodRadarProduct = 0;
sprintf ( message , "ERROR: #%d encountered reading radar file = %s"
" -- missing data substituted.", ierr, fname ) ;
printMessage(message, logFile);
*radarAvailFlag = 0 ;
for( i = 0; i < NUM_DPA_COLS; i++) sprintf ( message , "ERROR: #%d encountered reading radar file = %s"
{ " -- missing data substituted.", ierr, fname ) ;
for( j = 0; j < NUM_DPA_COLS; j++) printMessage(message, logFile);
radar[i][j] = RADAR_DEFAULT ; *radarAvailFlag = 0 ;
}
for( i = 0; i < NUM_DPA_COLS; i++)
} {
else //product is good, but just check for below minimum and correct to 0.0 for( j = 0; j < NUM_DPA_COLS; j++)
{ radar[i][j] = RADAR_DEFAULT ;
haveGoodRadarProduct = 1; }
for( i = 0; i < NUM_DPA_COLS; i++) }
{ else //product is good, but just check for below minimum and correct to 0.0
for( j = 0; j < NUM_DPA_COLS; j++) {
{ haveGoodRadarProduct = 1;
if(radar[i][j] < ACC_MIN)
radar[i][j] = 0.0 ; for( i = 0; i < NUM_DPA_COLS; i++)
} {
} for( j = 0; j < NUM_DPA_COLS; j++)
{
if(radar[i][j] < ACC_MIN)
} radar[i][j] = 0.0 ;
} }
}
}
}
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.") ;
printMessage(message, logFile); printMessage(message, logFile);
if(itim != 0) if(itim != 0)
{ {
sprintf ( message , "STATUS: no top-of-hour product found -- %d, " sprintf ( message , "STATUS: no top-of-hour product found -- %d, "
"product used instead.", itim ) ; "product used instead.", itim ) ;
printMessage(message, logFile); printMessage(message, logFile);
} }
for( i = 0; i < NUM_DPA_COLS; i++) for( i = 0; i < NUM_DPA_COLS; i++)
{ {
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 ;
} }
} }
} }
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, &currentHourObsTime);
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, &currentHourObsTime);
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;
} }