Omaha #4948 Improved Forced FFG handling

Former-commit-id: ed2caee1aa466aea15479acfa31e130be026a618
This commit is contained in:
Dave Hladky 2015-10-13 11:49:06 -05:00
parent e198c9a4e0
commit e5bed06160
2 changed files with 299 additions and 99 deletions

View file

@ -24,6 +24,7 @@ import java.util.List;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasin;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceInterpolation;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPTemplates;
import com.raytheon.uf.common.monitor.config.FFFGDataMgr;
import com.raytheon.uf.common.monitor.config.FFMPSourceConfigurationManager;
@ -45,6 +46,7 @@ import com.raytheon.uf.common.monitor.xml.SourceXML;
* 05/10/13 1919 mpduff If there are forced pfafs then the aggregate is forced.
* 05/22/13 1902 mpduff Added methods to get forced values.
* 06/17/13 2085 njensen Made forceIt() more thread safe
* 12 Oct, 2015 4948 dhladky Simplified Forcings, forcings now work for interpolated "fake" guidance.
*
* </pre>
*
@ -118,6 +120,14 @@ public class FFFGForceUtil {
return forceIt(ft, cBasin, pfafList, "NA");
}
/**
* Force values for this given basin
* @param ft
* @param cBasin
* @param pfafList
* @param domain
* @return
*/
private ForceUtilResult forceIt(FFMPTemplates ft, FFMPBasin cBasin,
List<Long> pfafList, String domain) {
boolean forced = false;
@ -219,6 +229,13 @@ public class FFFGForceUtil {
return retVal;
}
/**
* Get list of forced FFG basins
* @param source
* @param pfafList2
* @param ft
* @return
*/
private ArrayList<Long> getForcedBasins(String source,
List<Long> pfafList2, FFMPTemplates ft) {
FFFGDataMgr fdm = FFFGDataMgr.getInstance();
@ -247,6 +264,15 @@ public class FFFGForceUtil {
return forcedList;
}
/**
* Average forced FFG value for list of aggregate pfafs.
* @param pfafList
* @param forcedPfafs
* @param interpolation
* @param expiration
* @param templates
* @return
*/
public float getAvgForcedValue(List<Long> pfafList, List<Long> forcedPfafs,
FFMPGuidanceInterpolation interpolation, long expiration,
FFMPTemplates templates) {
@ -267,10 +293,8 @@ public class FFFGForceUtil {
return tvalue / i;
} else {
// TODO interpolated code under new ticket
return getInterpolatedForcedValue(interpolation, templates, forcedPfafs, INTERPOLATION_TYPE.AVG)/forcedPfafs.size();
}
return Float.NaN;
}
/**
@ -301,17 +325,16 @@ public class FFFGForceUtil {
value = dman.adjustValue(Float.NaN,
interpolation.getStandardSource(), pfaf, countyFips);
if (value < tvalue) {
if (value > tvalue) {
tvalue = value;
}
}
return tvalue;
} else {
// TODO interpolated code
}
return Float.NaN;
} else {
return getInterpolatedForcedValue(interpolation, templates, forcedPfafs, INTERPOLATION_TYPE.MAX);
}
}
/**
@ -340,21 +363,273 @@ public class FFFGForceUtil {
public List<Float> getForcedGuidValues(List<Long> pfafList,
List<Long> forcedPfafs,
FFMPGuidanceInterpolation ffmpGuidanceInterpolation,
long guidSourceExpiration, FFMPTemplates ft) {
long guidSourceExpiration, FFMPTemplates ft, String huc) {
List<Float> guidList = new ArrayList<Float>();
if (pfafList != null) {
for (Long pfaf : pfafList) {
if (pfaf == null) {
continue;
if (huc.equals(FFMPRecord.ALL) || huc.equals(FFMPRecord.COUNTY)) {
// Add all pfafs in list
for (Long pfaf : pfafList) {
if (pfaf == null) {
continue;
}
List<Long> pl = new ArrayList<Long>();
pl.add(pfaf);
float val = getAvgForcedValue(pl, forcedPfafs,
ffmpGuidanceInterpolation, guidSourceExpiration, ft);
guidList.add(val);
}
} else {
// Only add aggregate value to guidList for numbered hucs (second pfaf in list for forcing).
if (pfafList.get(1) != null) {
List<Long> pl = new ArrayList<Long>();
pl.add(pfafList.get(1));
float val = getAvgForcedValue(pl, forcedPfafs,
ffmpGuidanceInterpolation, guidSourceExpiration, ft);
guidList.add(val);
}
List<Long> pl = new ArrayList<Long>();
pl.add(pfaf);
float val = getAvgForcedValue(pl, forcedPfafs,
ffmpGuidanceInterpolation, guidSourceExpiration, ft);
guidList.add(val);
}
}
return guidList;
}
/**
* Calculate Interpolation of forced values for group of basins
*
* @param interpolation
* @param templates
* @param forcedPfafs
* @param type
* @return
*/
private Float getInterpolatedForcedValue(
FFMPGuidanceInterpolation interpolation, FFMPTemplates templates,
List<Long> forcedPfafs, INTERPOLATION_TYPE type) {
float value1 = 0.0f;
float value2 = 0.0f;
String source1 = interpolation.getSource1();
String source2 = interpolation.getSource2();
double ratioOffset = interpolation.getInterpolationOffset();
Float adjValue1 = 0.0f;
Float adjValue2 = 0.0f;
Float guidance = Float.NaN;
Float tvalue = 0.0f;
// interpolate from zero to first guidance
if (source1.equals(source2)) {
if ((ratioOffset == Double.NaN) || (ratioOffset == 0.0)) {
adjValue2 = Float.NaN;
}
FFFGDataMgr dman = FFFGDataMgr.getInstance();
for (long pfaf : forcedPfafs) {
long countyFips = templates.getCountyFipsByPfaf(pfaf);
templates.getCountyFipsByPfaf(pfaf);
if (dman.isExpired() == false) {
adjValue2 = dman.adjustValue(adjValue2, source2, pfaf,
countyFips);
}
if (!adjValue2.isNaN()) {
value2 = adjValue2.floatValue();
}
// straight from awips1 code ( FFMPdataUtils.C )
// We have an extrapolation to zero (the low side).
// The formula below yields:
// coeff = 0.62 for 0.25 time frame (endpoints.second)
// coeff = 0.75 for 0.50 time frame (endpoints.second)
// coeff = 0.88 for 0.75 time frame (endpoints.second)
// coeff = 0.95 for 0.90 time frame (endpoints.second)
// float mid, frac;
// mid = endpoints.second / 2.0;
// frac = 1.0 - ( ( duration - mid ) / mid );
// coeff = ( duration / endpoints.second ) + (0.25 * frac);
if ((interpolation.getHour(source1) == 0)
|| (source1.equals(source2) && (interpolation
.getHour(source2) == 1))) {
Double ratio = new Double(ratioOffset);
if (ratio.equals(.25)) {
guidance = (float) (.62 * value2);
} else if (ratio.equals(.5)) {
guidance = (float) (.75 * value2);
} else if (ratio.equals(.75)) {
guidance = (float) (.88 * value2);
} else if (ratio.equals(.9)) {
guidance = (float) (.95 * value2);
}
}
if (type == INTERPOLATION_TYPE.MAX) {
if (guidance > tvalue) {
tvalue = guidance;
}
} else if (type == INTERPOLATION_TYPE.AVG) {
tvalue += guidance;
}
}// otherwise interpolate linearly I guess
} else {
// check if values at the source do not exist
FFFGDataMgr dman = FFFGDataMgr.getInstance();
for (long pfaf : forcedPfafs) {
long countyFips = templates.getCountyFipsByPfaf(pfaf);
templates.getCountyFipsByPfaf(pfaf);
if (dman.isExpired() == false) {
adjValue1 = dman.adjustValue(adjValue1, source1, pfaf,
countyFips);
}
if (!adjValue1.isNaN()) {
value1 = adjValue1.floatValue();
}
if (dman.isExpired() == false) {
adjValue2 = dman.adjustValue(adjValue2, source2, pfaf,
countyFips);
}
if (!adjValue2.isNaN()) {
value2 = adjValue2.floatValue();
}
if ((value1 == Float.NaN) || (value2 == Float.NaN)) {
guidance = Float.NaN;
}
guidance = (float) (value1 + ((value2 - value1) * ratioOffset));
if (type == INTERPOLATION_TYPE.MAX) {
if (guidance > tvalue) {
tvalue = guidance;
}
} else if (type == INTERPOLATION_TYPE.AVG) {
tvalue += guidance;
}
}
}
return tvalue;
}
/**
* Find forced value for individual basin
*
* @param templates
* @param cBasinPfaf
* @param guidType
* @return
*/
public Float getInterpolatedForcedValue(FFMPTemplates templates,
long cBasinPfaf, String guidType) {
float value1 = 0.0f;
float value2 = 0.0f;
FFMPGuidanceInterpolation interpolate = resource
.getGuidanceInterpolators().get(guidType);
String source1 = interpolate.getSource1();
String source2 = interpolate.getSource2();
double ratioOffset = interpolate.getInterpolationOffset();
Float adjValue1 = 0.0f;
Float adjValue2 = 0.0f;
float guidance = 0.0f;
// interpolate from zero to first guidance
if (source1.equals(source2)) {
if ((ratioOffset == Double.NaN) || (ratioOffset == 0.0)) {
adjValue2 = Float.NaN;
}
FFFGDataMgr dman = FFFGDataMgr.getInstance();
if (dman.isExpired() == false) {
adjValue2 = dman
.adjustValue(adjValue2, source2, cBasinPfaf, 0l);
}
if (!adjValue2.isNaN()) {
value2 = adjValue2.floatValue();
}
// straight from awips1 code ( FFMPdataUtils.C )
// We have an extrapolation to zero (the low side).
// The formula below yields:
// coeff = 0.62 for 0.25 time frame (endpoints.second)
// coeff = 0.75 for 0.50 time frame (endpoints.second)
// coeff = 0.88 for 0.75 time frame (endpoints.second)
// coeff = 0.95 for 0.90 time frame (endpoints.second)
// float mid, frac;
// mid = endpoints.second / 2.0;
// frac = 1.0 - ( ( duration - mid ) / mid );
// coeff = ( duration / endpoints.second ) + (0.25 * frac);
if ((interpolate.getHour(source1) == 0)
|| (source1.equals(source2) && (interpolate
.getHour(source2) == 1))) {
Double ratio = new Double(ratioOffset);
if (ratio.equals(.25)) {
guidance = (float) (.62 * value2);
} else if (ratio.equals(.5)) {
guidance = (float) (.75 * value2);
} else if (ratio.equals(.75)) {
guidance = (float) (.88 * value2);
} else if (ratio.equals(.9)) {
guidance = (float) (.95 * value2);
}
}
// otherwise interpolate linearly I guess
} else {
// check if values at the source do not exist
FFFGDataMgr dman = FFFGDataMgr.getInstance();
if (dman.isExpired() == false) {
adjValue1 = dman
.adjustValue(adjValue1, source1, cBasinPfaf, 0l);
}
if (!adjValue1.isNaN()) {
value1 = adjValue1.floatValue();
}
if (dman.isExpired() == false) {
adjValue2 = dman
.adjustValue(adjValue2, source2, cBasinPfaf, 0l);
}
if (!adjValue2.isNaN()) {
value2 = adjValue2.floatValue();
}
if ((value1 == Float.NaN) || (value2 == Float.NaN)) {
guidance = Float.NaN;
}
guidance = (float) (value1 + ((value2 - value1) * ratioOffset));
}
return guidance;
}
/**
*
* INTERPOLATION type MAX, AVG
*
* @author dhladky
* @version 1.0
*/
public enum INTERPOLATION_TYPE {
MAX("MAX"), AVG("AVG");
private final String itype;
private INTERPOLATION_TYPE(String name) {
itype = name;
}
public String getInterpolationType() {
return itype;
}
};
}

View file

@ -29,7 +29,6 @@ import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasin;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinData;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPBasinMetaData;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceBasin;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPGuidanceInterpolation;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPRecord.FIELDS;
import com.raytheon.uf.common.dataplugin.ffmp.FFMPTemplates;
@ -62,6 +61,7 @@ import com.raytheon.uf.viz.monitor.ffmp.ui.dialogs.FfmpTableConfigData;
* Jun 11, 2013 2085 njensen Initial creation
* Jul 15, 2013 2184 dhladky Remove all HUC's for storage except ALL
* Apr 30, 2014 2060 njensen Safety checks for null guidance
* Oct 12, 2015 4948 dhladky Improved forced FFG handling.
*
* </pre>
*
@ -594,6 +594,7 @@ public class FFMPRowGenerator implements Runnable {
// run over each guidance type
int i = 0;
for (String guidType : guidBasins.keySet()) {
guidance = Float.NaN;
diffValue = Float.NaN;
ratioValue = Float.NaN;
@ -690,7 +691,7 @@ public class FFMPRowGenerator implements Runnable {
resource.getGuidanceInterpolators().get(
guidType), resource
.getGuidSourceExpiration(guidType),
ft);
ft, huc);
}
if ((!qpes.isEmpty())
@ -927,84 +928,8 @@ public class FFMPRowGenerator implements Runnable {
}
}
} else {
float value1 = 0.0f;
float value2 = 0.0f;
FFMPGuidanceInterpolation interpolate = resource.getGuidanceInterpolators().get(guidType);
String source1 = interpolate.getSource1();
String source2 = interpolate.getSource2();
double ratioOffset = interpolate.getInterpolationOffset();
Float adjValue1 = 0.0f;
Float adjValue2 = 0.0f;
// interpolate from zero to first guidance
if (source1.equals(source2)) {
if ((ratioOffset == Double.NaN) || (ratioOffset == 0.0)) {
adjValue2 = Float.NaN;
}
FFFGDataMgr dman = FFFGDataMgr.getInstance();
if (dman.isExpired() == false) {
adjValue2 = dman.adjustValue(adjValue2, source2, cBasinPfaf, 0l);
}
if (!adjValue2.isNaN()) {
value2 = adjValue2.floatValue();
}
// straight from awips1 code ( FFMPdataUtils.C )
// We have an extrapolation to zero (the low side).
// The formula below yields:
// coeff = 0.62 for 0.25 time frame (endpoints.second)
// coeff = 0.75 for 0.50 time frame (endpoints.second)
// coeff = 0.88 for 0.75 time frame (endpoints.second)
// coeff = 0.95 for 0.90 time frame (endpoints.second)
// float mid, frac;
// mid = endpoints.second / 2.0;
// frac = 1.0 - ( ( duration - mid ) / mid );
// coeff = ( duration / endpoints.second ) + (0.25 * frac);
if ((interpolate.getHour(source1) == 0)
|| (source1.equals(source2) && (interpolate
.getHour(source2) == 1))) {
Double ratio = new Double(ratioOffset);
if (ratio.equals(.25)) {
guidance = (float) (.62 * value2);
} else if (ratio.equals(.5)) {
guidance = (float) (.75 * value2);
} else if (ratio.equals(.75)) {
guidance = (float) (.88 * value2);
} else if (ratio.equals(.9)) {
guidance = (float) (.95 * value2);
}
}
// otherwise interpolate linearly I guess
} else {
// check if values at the source do not exist
FFFGDataMgr dman = FFFGDataMgr.getInstance();
if (dman.isExpired() == false) {
adjValue1 = dman.adjustValue(adjValue1, source1, cBasinPfaf, 0l);
}
if (!adjValue1.isNaN()) {
value1 = adjValue1.floatValue();
}
if (dman.isExpired() == false) {
adjValue2 = dman.adjustValue(adjValue2, source2, cBasinPfaf, 0l);
}
if (!adjValue2.isNaN()) {
value2 = adjValue2.floatValue();
}
if ((value1 == Float.NaN) || (value2 == Float.NaN)) {
guidance = Float.NaN;
}
guidance = (float)(value1 + ((value2 - value1) * ratioOffset));
}
guidance = forceUtil.getInterpolatedForcedValue(ft, cBasinPfaf,
guidType);
}
return new FFMPTableCellData(FIELDS.GUIDANCE, guidance, forced);