Omaha #4948 Improved Forced FFG handling
Former-commit-id: ed2caee1aa466aea15479acfa31e130be026a618
This commit is contained in:
parent
e198c9a4e0
commit
e5bed06160
2 changed files with 299 additions and 99 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue