Omaha #3756 Add configurable precipitation accumulation grib post processor.
Change-Id: I8cf2a4f3e06f0645fc2348e1a8068f0ef8ce63a8 Former-commit-id: d731f3e21b9c1eac5659ac44de90cfab1013b71b
This commit is contained in:
parent
e198c9a4e0
commit
d686433642
34 changed files with 1663 additions and 1494 deletions
|
@ -32,6 +32,7 @@ fi
|
|||
let "MAX_MEM = GRIB_DECODE_THREADS * 128" # in Meg
|
||||
let "GRIB_MAX_GRID_POINTS = GRIB_DECODE_THREADS * 25000000"
|
||||
let "GRID_PERSIST_THREADS = GRIB_DECODE_THREADS / 2"
|
||||
let "GRID_POSTPROCESS_THREADS = 1"
|
||||
let "GRID_MAX_PERSIST_MEMORY_IN_MB = GRID_PERSIST_THREADS * 50"
|
||||
|
||||
export INIT_MEM=128 # in Meg
|
||||
|
@ -39,6 +40,7 @@ export MAX_MEM
|
|||
export GRIB_DECODE_THREADS
|
||||
export GRIB_MAX_GRID_POINTS
|
||||
export GRID_PERSIST_THREADS
|
||||
export GRID_POSTPROCESS_THREADS
|
||||
export GRID_MAX_PERSIST_MEMORY_IN_MB
|
||||
|
||||
export METADATA_POOL_MAX=10
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.ArrayList;
|
|||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.decoderpostprocessors.IDecoderPostProcessor;
|
||||
import com.raytheon.edex.plugin.grib.decoderpostprocessors.DecoderPostProcessor;
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
|
@ -16,23 +16,24 @@ import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
|||
|
||||
/**
|
||||
* Abstract class to generate 1-hour precip grids
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ------------- --------------------------
|
||||
* Sep 05, 2014 M. Foster Initial creation
|
||||
*
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author matthew.foster
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class OneHrPrecipGridProcessor implements IDecoderPostProcessor {
|
||||
public abstract class OneHrPrecipGridProcessor extends DecoderPostProcessor {
|
||||
/** The number of seconds in 1 hour */
|
||||
protected static final int SECONDS_IN_1_HR = 3600;
|
||||
|
||||
|
|
38
deltaScripts/16.2.1/DR3756/updatePostProcessorOverrides.sh
Normal file
38
deltaScripts/16.2.1/DR3756/updatePostProcessorOverrides.sh
Normal file
|
@ -0,0 +1,38 @@
|
|||
#!/bin/bash
|
||||
# AWIPS2 #3756
|
||||
#
|
||||
# Updates the non-base postProcessedModels.xml localization files to replace
|
||||
# precipitation post-processors that have been removed from the baseline with
|
||||
# the configurable PrecipAccumPostProcessor.
|
||||
#
|
||||
#
|
||||
|
||||
for file in `find /awips2/edex/data/utility/edex_static/ -name postProcessedModels.xml`
|
||||
do
|
||||
level=`echo $file | cut -f 7 -d '/'`
|
||||
if [ $level != 'base' ] # base is assumed to be correct as deployed.
|
||||
then
|
||||
checkForUpdate=`grep PrecipAccumPostProcessor $file`
|
||||
if [ "${checkForUpdate}" == "" ]
|
||||
then
|
||||
echo "Updating $file"
|
||||
# create a copy of the file with the changes in a temporary file
|
||||
newFile="${file}_`date +%s`.dr3756"
|
||||
cat $file | sed 's/com.raytheon.edex.plugin.grib.decoderpostprocessors.//g' | sed -r 's/Nam80PostProcessor|CanadianNHPostProcessor|CanadianRegPostProcessor|gov.noaa.nws.crh.edex.grib.decoderpostprocessor.GFS20PostProcessor/PrecipAccumPostProcessor/g' | sed 's/<processorName>ECMWFHiResProcessor<\/processorName>/<processorName>ECMWFHiResProcessor<\/processorName>\n <processorName>PrecipAccumPostProcessor<\/processorName>/g' > $newFile
|
||||
if [ -s $newFile ]
|
||||
then
|
||||
chmod --reference=$file $newFile
|
||||
chown --reference=$file $newFile
|
||||
mv $newFile $file
|
||||
else
|
||||
echo "Failed to update $file"
|
||||
if [ -e $newFile ]
|
||||
then
|
||||
rm $newFile
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "$file has already been updated and will be skipped."
|
||||
fi
|
||||
fi
|
||||
done
|
|
@ -25,23 +25,20 @@
|
|||
<list>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.ARIPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.CPCoutlookGribPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.CanadianNHPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.CanadianRegPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.ECMWFHiResProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.EnsembleGridAssembler</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.FFGGribPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.GFSProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.HPCqpfPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.HWRFPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.LapsPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.LiftedIndexPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.MSASPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.Nam80PostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.OverwriteGribPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.RTMAGribPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.RUC130GribPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.RUC236GribPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.TemperatureCorrectionPostProcessor</value>
|
||||
<value>com.raytheon.edex.plugin.grib.decoderpostprocessors.precipitation.PrecipAccumPostProcessor</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
@ -75,6 +72,7 @@
|
|||
|
||||
<endpoint id="gribSplitJmsEndpoint" uri="jms-durable:queue:Ingest.GribSplit?concurrentConsumers=${GRIB_SPLIT_THREADS}"/>
|
||||
<endpoint id="gribDecodeJmsEndpoint" uri="jms-durable:queue:Ingest.GribDecode?concurrentConsumers=${GRIB_DECODE_THREADS}"/>
|
||||
<endpoint id="gridPostProcessesJmsEndpoint" uri="jms-durable:queue:Grid.PostProcess?concurrentConsumers=${GRID_POSTPROCESS_THREADS}"/>
|
||||
|
||||
<!-- Begin Grib Decode Route -->
|
||||
<route id="gribSplitIngestRoute">
|
||||
|
@ -139,5 +137,25 @@
|
|||
</split>
|
||||
</multicast>
|
||||
</route>
|
||||
|
||||
<!--
|
||||
Does a second round of post processing to generate new records
|
||||
derived from recently persisted records.
|
||||
-->
|
||||
<route id="gridPostProcessRoute">
|
||||
<from ref="gridPostProcessesJmsEndpoint" />
|
||||
<doTry>
|
||||
<pipeline>
|
||||
<bean ref="serializationUtil" method="transformFromThrift" />
|
||||
<!-- send for processing -->
|
||||
<bean ref="gribPostProcessor" method="processPersisted" />
|
||||
<bean ref="gridPersister" method="persist"/>
|
||||
</pipeline>
|
||||
<doCatch>
|
||||
<exception>java.lang.Throwable</exception>
|
||||
<to uri="log:grib?level=ERROR"/>
|
||||
</doCatch>
|
||||
</doTry>
|
||||
</route>
|
||||
</camelContext>
|
||||
</beans>
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -34,6 +34,7 @@ import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Sep 21, 2015 4756 dhladky Initial Creation
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -41,53 +42,53 @@ import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
|||
* @version 1
|
||||
* */
|
||||
|
||||
public class ARIPostProcessor implements IDecoderPostProcessor {
|
||||
|
||||
public class ARIPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
/** name of extraAttribute variable from GribDecoder.py */
|
||||
private static final String FORECAST_INTERVAL = "forecastInterval";
|
||||
|
||||
|
||||
/** name of extraAttribute variable from GribDecoder.py */
|
||||
private static final String FORECAST_INTERVAL_UNIT = "forecastIntervalUnit";
|
||||
|
||||
|
||||
/** 30 minute record identifier **/
|
||||
private static final String REFZC = "REFZC";
|
||||
|
||||
|
||||
/** 1 hr record identifier **/
|
||||
private static final String REFZI = "REFZI";
|
||||
|
||||
|
||||
/** 3 hr record identifier **/
|
||||
private static final String RETOP = "RETOP";
|
||||
|
||||
|
||||
/** 6 hr record identifier **/
|
||||
private static final String REFD = "REFD";
|
||||
|
||||
|
||||
/** 12 hr record identifier **/
|
||||
private static final String REFC = "REFC";
|
||||
|
||||
|
||||
/** Year **/
|
||||
private static final String YR = "YR";
|
||||
|
||||
|
||||
/** ARI (Archival Recurrence Interval **/
|
||||
private static final String ARI = "ARI";
|
||||
|
||||
|
||||
/** 30 min comparison time **/
|
||||
private static final String MIN30 = "30";
|
||||
|
||||
|
||||
/** 1 hour comparison time **/
|
||||
private static final String HOUR1 = "1";
|
||||
|
||||
|
||||
/** 3 hour comparison time **/
|
||||
private static final String HOUR3 = "3";
|
||||
|
||||
|
||||
/** 6 hour comparison time **/
|
||||
private static final String HOUR6 = "6";
|
||||
|
||||
|
||||
/** 12 hour comparison time **/
|
||||
private static final String HOUR12 = "12";
|
||||
|
||||
|
||||
/** ARI is precip in mm **/
|
||||
private static final String UNIT = "mm";
|
||||
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
|
||||
|
@ -123,7 +124,7 @@ public class ARIPostProcessor implements IDecoderPostProcessor {
|
|||
/**
|
||||
* Create a new parameter abbreviation based on the forecast year and
|
||||
* interval period.
|
||||
*
|
||||
*
|
||||
* @param record
|
||||
* @param forecastYear
|
||||
* @return
|
||||
|
@ -160,13 +161,12 @@ public class ARIPostProcessor implements IDecoderPostProcessor {
|
|||
throw new IllegalArgumentException("ARI paramName " + paramAbbrev
|
||||
+ " is not a valid param for ARI postprocessing");
|
||||
}
|
||||
|
||||
|
||||
// Give it a new name/description/unit
|
||||
record.getParameter().setAbbreviation(sb.toString());
|
||||
record.getParameter().setName(sb2.toString());
|
||||
record.getParameter().setUnitString(UNIT);
|
||||
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -49,13 +49,14 @@ import com.raytheon.uf.common.time.DataTime;
|
|||
* Mar 09, 2011 4243 porricel Initial Creation
|
||||
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
||||
* Oct 15, 2013 2473 bsteffen Removed deprecated and unused code.
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author
|
||||
* @version
|
||||
*/
|
||||
public class CPCoutlookGribPostProcessor implements IDecoderPostProcessor {
|
||||
public class CPCoutlookGribPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
|
|
|
@ -1,183 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridConstants;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
||||
import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
||||
|
||||
/**
|
||||
* Grib post processor implementation to generate 6-hr precipitation grids from
|
||||
* run accumulated total precipitation
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 18, 2012 porricel Initial Creation
|
||||
* Oct 15, 2013 2473 bsteffen Removed unused method argument.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class CanadianNHPostProcessor extends SixHrPrecipGridProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
// Post process the data if this is a Total Precipitation grid
|
||||
if (record.getParameter().getAbbreviation().equals("TPrun")) {
|
||||
return super.process(record);
|
||||
}
|
||||
return new GridRecord[] { record };
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<GridRecord> getPrecipInventory(Date refTime)
|
||||
throws GribException {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating grib dao!", e);
|
||||
}
|
||||
DatabaseQuery query = new DatabaseQuery(GridRecord.class);
|
||||
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, "TPrun");
|
||||
query.addQueryParam(GridConstants.DATASET_ID, "Canadian-NH");
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addOrder("dataTime.fcstTime", true);
|
||||
try {
|
||||
return (List<GridRecord>) dao.queryByCriteria(query);
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException(
|
||||
"Error getting Precip inventory for Canadian-NH!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<Integer> getPrecip6hrInventory(Date refTime)
|
||||
throws GribException {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating grib dao!", e);
|
||||
}
|
||||
DatabaseQuery query = new DatabaseQuery(GridRecord.class);
|
||||
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, "TP6hr");
|
||||
query.addQueryParam(GridConstants.DATASET_ID, "Canadian-NH");
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addReturnedField("dataTime.fcstTime");
|
||||
try {
|
||||
return (List<Integer>) dao.queryByCriteria(query);
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException(
|
||||
"Error getting Precip inventory for Canadian-NH!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the 6 hour accumulated grid from the run accumulated
|
||||
* precipitation grids. This function will look in the inventory and
|
||||
* generate any 6 hr grids that can be generated.
|
||||
*
|
||||
* @param record
|
||||
* The grib record for which to generate the 6 hour accumulated
|
||||
* precipitation grid
|
||||
* @return The generated 6-hr precipitation grids
|
||||
* @throws GribException
|
||||
*/
|
||||
protected synchronized GridRecord[] generate6hrPrecipGrids(GridRecord record)
|
||||
throws GribException {
|
||||
|
||||
// The current run accumulated precipitation grid inventory in the
|
||||
// database
|
||||
List<GridRecord> precipInventory = getPrecipInventory(record
|
||||
.getDataTime().getRefTime());
|
||||
|
||||
// The current 6-hr precipitation grid inventory in the database
|
||||
List<Integer> precip6hrInventory = getPrecip6hrInventory(record
|
||||
.getDataTime().getRefTime());
|
||||
|
||||
// Adds the current record to the precip inventory
|
||||
float[] currentData = (float[]) record.getMessageData();
|
||||
record.setMessageData(currentData);
|
||||
precipInventory.add(record);
|
||||
|
||||
// Examine each grid in the inventory and generate the 6hr precipitation
|
||||
// grid if possible
|
||||
List<GridRecord> generatedRecords = new ArrayList<GridRecord>();
|
||||
for (int i = 0; i < precipInventory.size(); i++) {
|
||||
// Check if the 6hr precipitation grid has already been produced
|
||||
if (!precip6hrInventory.contains(precipInventory.get(i)
|
||||
.getDataTime().getFcstTime())) {
|
||||
// If the precipitation grid has not been produced, generate it
|
||||
List<GridRecord> generated6hrPrecips = generate6hrPrecip(
|
||||
precipInventory.get(i), precipInventory);
|
||||
for (GridRecord newRecord : generated6hrPrecips) {
|
||||
// Add the generated grid to the current inventory
|
||||
if (newRecord != null) {
|
||||
precip6hrInventory.add(newRecord.getDataTime()
|
||||
.getFcstTime());
|
||||
generatedRecords.add(newRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return generatedRecords.toArray(new GridRecord[] {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the new data by subtracting the previous inventory data from
|
||||
* the current data
|
||||
*
|
||||
* @param inventoryData
|
||||
* The data from the previous precipitation record
|
||||
* @param newData
|
||||
* The data from the current precipitation record
|
||||
*/
|
||||
protected void calculatePrecipValues(float[] inventoryData, float[] newData) {
|
||||
for (int i = 0; i < inventoryData.length; i++) {
|
||||
newData[i] = newData[i] - inventoryData[i];
|
||||
if (newData[i] < 0) {
|
||||
newData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,184 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridConstants;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
||||
import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
||||
|
||||
/**
|
||||
* Grib post processor implementation to generate 3-hr precipitation grids from
|
||||
* run accumulated total precipitation
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Jan 18, 2012 porricel Initial Creation
|
||||
* Oct 15, 2013 2473 bsteffen Removed unused method argument.
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class CanadianRegPostProcessor extends ThreeHrPrecipGridProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
// Post process the data if this is a Total Precipitation grid
|
||||
if (record.getParameter().getAbbreviation().equals("TPrun")) {
|
||||
return super.process(record);
|
||||
}
|
||||
return new GridRecord[] { record };
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<GridRecord> getPrecipInventory(Date refTime)
|
||||
throws GribException {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating grib dao!", e);
|
||||
}
|
||||
DatabaseQuery query = new DatabaseQuery(GridRecord.class);
|
||||
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, "TPrun");
|
||||
query.addQueryParam(GridConstants.DATASET_ID, "Canadian-Reg");
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addOrder("dataTime.fcstTime", true);
|
||||
try {
|
||||
return (List<GridRecord>) dao.queryByCriteria(query);
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException(
|
||||
"Error getting Precip inventory for Canadian-Reg!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<Integer> getPrecip3hrInventory(Date refTime)
|
||||
throws GribException {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating grib dao!", e);
|
||||
}
|
||||
DatabaseQuery query = new DatabaseQuery(GridRecord.class);
|
||||
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, "TP3hr");
|
||||
query.addQueryParam(GridConstants.DATASET_ID, "Canadian-Reg");
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addReturnedField("dataTime.fcstTime");
|
||||
try {
|
||||
return (List<Integer>) dao.queryByCriteria(query);
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException(
|
||||
"Error getting Precip inventory for Canadian-Reg!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the 3 hour accumulated grid from the run accumulated
|
||||
* precipitation grids. This function will look in the inventory and
|
||||
* generate any 3 hr grids that can be generated.
|
||||
*
|
||||
* @param record
|
||||
* The grib record for which to generate the 3 hour accumulated
|
||||
* precipitation grid
|
||||
* @return The generated 3-hr precipitation grids
|
||||
* @throws GribException
|
||||
*/
|
||||
protected synchronized GridRecord[] generate3hrPrecipGrids(GridRecord record)
|
||||
throws GribException {
|
||||
|
||||
// The current run accumulated precipitation grid inventory in the
|
||||
// database
|
||||
List<GridRecord> precipInventory = getPrecipInventory(record
|
||||
.getDataTime().getRefTime());
|
||||
|
||||
// The current 3-hr precipitation grid inventory in the database
|
||||
List<Integer> precip3hrInventory = getPrecip3hrInventory(record
|
||||
.getDataTime().getRefTime());
|
||||
|
||||
// Adds the current record to the precip inventory
|
||||
float[] currentData = (float[]) record.getMessageData();
|
||||
record.setMessageData(currentData);
|
||||
precipInventory.add(record);
|
||||
|
||||
// Examine each grid in the inventory and generate the 3hr precipitation
|
||||
// grid if possible
|
||||
List<GridRecord> generatedRecords = new ArrayList<GridRecord>();
|
||||
for (int i = 0; i < precipInventory.size(); i++) {
|
||||
// Check if the 3hr precipitation grid has already been produced
|
||||
if (!precip3hrInventory.contains(precipInventory.get(i)
|
||||
.getDataTime().getFcstTime())) {
|
||||
// If the precipitation grid has not been produced, generate it
|
||||
List<GridRecord> generated3hrPrecips = generate3hrPrecip(
|
||||
precipInventory.get(i), precipInventory);
|
||||
for (GridRecord newRecord : generated3hrPrecips) {
|
||||
// Add the generated grid to the current inventory
|
||||
if (newRecord != null) {
|
||||
precip3hrInventory.add(newRecord.getDataTime()
|
||||
.getFcstTime());
|
||||
generatedRecords.add(newRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return generatedRecords.toArray(new GridRecord[] {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the new data by subtracting the previous inventory data from
|
||||
* the current data
|
||||
*
|
||||
* @param inventoryData
|
||||
* The data from the previous precipitation record
|
||||
* @param newData
|
||||
* The data from the current precipitation record
|
||||
*/
|
||||
protected void calculatePrecipValues(float[] inventoryData, float[] newData) {
|
||||
for (int i = 0; i < inventoryData.length; i++) {
|
||||
newData[i] = newData[i] - inventoryData[i];
|
||||
if (newData[i] < 0) {
|
||||
newData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
|
||||
import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
||||
|
||||
/**
|
||||
* Grib decoder post processor interface
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 8/30/10 5875 bphillip Initial Creation
|
||||
* Oct 07, 2015 3756 nabowle Switch interface to abstract class,
|
||||
* rename from IDecoderPostProcessor, add
|
||||
* getMessageData(), getType(), and
|
||||
* relevant enum,
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public abstract class DecoderPostProcessor {
|
||||
|
||||
/**
|
||||
* Processes the provided record to see if it needs to be post processed
|
||||
*
|
||||
* @param record
|
||||
* The record to examine to determine if it needs to be post
|
||||
* processed
|
||||
* @return The array of grib records including any created during post
|
||||
* processing
|
||||
* @throws GribException
|
||||
*/
|
||||
public abstract GridRecord[] process(GridRecord record)
|
||||
throws GribException;
|
||||
|
||||
/** Get the type of post processor. Defaults to {@link #PRE_PERSIST}. */
|
||||
public PostProcessorType getType() {
|
||||
return PostProcessorType.PRE_PERSIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message data for a record. If the record's messagedata is null,
|
||||
* the data will be retrieved from the data store, set on the record, and
|
||||
* returned.
|
||||
*
|
||||
* @param record
|
||||
* The record to get the message data for.
|
||||
* @return
|
||||
* @throws GribException
|
||||
*/
|
||||
protected float[] getMessageData(GridRecord record) throws GribException {
|
||||
float[] data = (float[]) record.getMessageData();
|
||||
if (data == null) {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
record.setMessageData(((FloatDataRecord) dao.getHDF5Data(
|
||||
record, -1)[0]).getFloatData());
|
||||
data = (float[]) record.getMessageData();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error populating grib data", e);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the types of IDecoderPostProcessors.
|
||||
*
|
||||
* It is expected that {@link #POST_PERSIST} processors do not return the
|
||||
* input record.
|
||||
*/
|
||||
public static enum PostProcessorType {
|
||||
/**
|
||||
* Processors that process a GridRecord that was just decoded and before
|
||||
* being persisted.
|
||||
*/
|
||||
PRE_PERSIST,
|
||||
|
||||
/**
|
||||
* Processors that process a GridRecord after it was persisted. It is
|
||||
* expected these processors do not return the input record.
|
||||
*/
|
||||
POST_PERSIST
|
||||
}
|
||||
}
|
|
@ -1,187 +1,59 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridConstants;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
||||
import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
||||
|
||||
/**
|
||||
* Grib post processor implementation to generate 6-hr precipitation grids from
|
||||
* run accumulated total precipitation
|
||||
*
|
||||
* Grib post processor implementation to scale TP-ECMWF data to the proper unit.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Aug 30, 2010 5875 bphillip Initial Creation
|
||||
* Oct 15, 2013 2473 bsteffen Removed unused method argument.
|
||||
*
|
||||
*
|
||||
* Oct 07, 2015 3756 nabowle Changed to only do data scaling. Extends
|
||||
* DecoderPostProcessor.
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class ECMWFHiResProcessor extends SixHrPrecipGridProcessor {
|
||||
public class ECMWFHiResProcessor extends DecoderPostProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
// Post process the data if this is a Total Precipitation grid
|
||||
if (record.getParameter().getAbbreviation().equals("TP-ECMWF")) {
|
||||
return super.process(record);
|
||||
float[] data = getMessageData(record);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
data[i] = data[i] * 1000;
|
||||
}
|
||||
}
|
||||
return new GridRecord[] { record };
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<GridRecord> getPrecipInventory(Date refTime)
|
||||
throws GribException {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating grib dao!", e);
|
||||
}
|
||||
DatabaseQuery query = new DatabaseQuery(GridRecord.class);
|
||||
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, "TP-ECMWF");
|
||||
query.addQueryParam(GridConstants.DATASET_ID, "ECMWF-HiRes");
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addOrder("dataTime.fcstTime", true);
|
||||
try {
|
||||
return (List<GridRecord>) dao.queryByCriteria(query);
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException(
|
||||
"Error getting Precip inventory for ECMWF!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<Integer> getPrecip6hrInventory(Date refTime)
|
||||
throws GribException {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating grib dao!", e);
|
||||
}
|
||||
DatabaseQuery query = new DatabaseQuery(GridRecord.class);
|
||||
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, "TP6hr");
|
||||
query.addQueryParam(GridConstants.DATASET_ID, "ECMWF-HiRes");
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addReturnedField("dataTime.fcstTime");
|
||||
try {
|
||||
return (List<Integer>) dao.queryByCriteria(query);
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException(
|
||||
"Error getting Precip inventory for ECMWF!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the 6 hour accumulated grid from the run accumulated
|
||||
* precipitation grids. This function will look in the inventory and
|
||||
* generate any 6 hr grids that can be generated.
|
||||
*
|
||||
* @param record
|
||||
* The grib record for which to generate the 6 hour accumulated
|
||||
* precipitation grid
|
||||
* @return The generated 6-hr precipitation grids
|
||||
* @throws GribException
|
||||
*/
|
||||
protected synchronized GridRecord[] generate6hrPrecipGrids(GridRecord record)
|
||||
throws GribException {
|
||||
|
||||
// The current run accumulated precipitation grid inventory in the
|
||||
// database
|
||||
List<GridRecord> precipInventory = getPrecipInventory(record
|
||||
.getDataTime().getRefTime());
|
||||
|
||||
// The current 6-hr precipitation grid inventory in the database
|
||||
List<Integer> precip6hrInventory = getPrecip6hrInventory(record
|
||||
.getDataTime().getRefTime());
|
||||
|
||||
// Adds the current record to the precip inventory
|
||||
float[] currentData = (float[]) record.getMessageData();
|
||||
for (int i = 0; i < currentData.length; i++) {
|
||||
currentData[i] = currentData[i] * 1000;
|
||||
}
|
||||
record.setMessageData(currentData);
|
||||
precipInventory.add(record);
|
||||
|
||||
// Examine each grid in the inventory and generate the 6hr precipitation
|
||||
// grid if possible
|
||||
List<GridRecord> generatedRecords = new ArrayList<GridRecord>();
|
||||
for (int i = 0; i < precipInventory.size(); i++) {
|
||||
// Check if the 6hr precipitation grid has already been produced
|
||||
if (!precip6hrInventory.contains(precipInventory.get(i)
|
||||
.getDataTime().getFcstTime())) {
|
||||
// If the precipitation grid has not been produced, generate it
|
||||
List<GridRecord> generated6hrPrecips = generate6hrPrecip(
|
||||
precipInventory.get(i), precipInventory);
|
||||
for (GridRecord newRecord : generated6hrPrecips) {
|
||||
// Add the generated grid to the current inventory
|
||||
if (newRecord != null) {
|
||||
precip6hrInventory.add(newRecord.getDataTime()
|
||||
.getFcstTime());
|
||||
generatedRecords.add(newRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return generatedRecords.toArray(new GridRecord[] {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the new data by subtracting the previous inventory data from
|
||||
* the current data
|
||||
*
|
||||
* @param inventoryData
|
||||
* The data from the previous precipitation record
|
||||
* @param newData
|
||||
* The data from the current precipitation record
|
||||
*/
|
||||
protected void calculatePrecipValues(float[] inventoryData, float[] newData) {
|
||||
for (int i = 0; i < inventoryData.length; i++) {
|
||||
newData[i] = newData[i] - inventoryData[i];
|
||||
if (newData[i] < 0) {
|
||||
newData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -51,11 +51,11 @@ import com.raytheon.uf.edex.plugin.grid.PartialGrid;
|
|||
* The EnsembleGridAssembler class is part of the ingest process for grib data.
|
||||
* Some grib model come in as octants. This class will combine those octants
|
||||
* into a single grid
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Apr 09, 2010 4638 bphillip Initial Creation
|
||||
|
@ -70,12 +70,13 @@ import com.raytheon.uf.edex.plugin.grid.PartialGrid;
|
|||
* Jul 21, 2014 3373 bclement JAXB manager api changes
|
||||
* Aug 18, 2014 4360 rferrel Set secondaryId in {@link #createAssembledRecord(GridRecord, CompositeModel)}
|
||||
* Sep 09, 2015 4868 rjpeter Updated to be stored in partial grids as part of normal route.
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class EnsembleGridAssembler implements IDecoderPostProcessor {
|
||||
public class EnsembleGridAssembler extends DecoderPostProcessor {
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(EnsembleGridAssembler.class);
|
||||
|
||||
|
@ -145,7 +146,7 @@ public class EnsembleGridAssembler implements IDecoderPostProcessor {
|
|||
|
||||
/**
|
||||
* Gets the composite model for the provided model name0
|
||||
*
|
||||
*
|
||||
* @param modelName
|
||||
* The model name to determine the composite model name for
|
||||
* @return The composite model. Null if not found
|
||||
|
@ -175,7 +176,7 @@ public class EnsembleGridAssembler implements IDecoderPostProcessor {
|
|||
|
||||
/**
|
||||
* Merges the data from a GridRecord into the composite GridRecord
|
||||
*
|
||||
*
|
||||
* @param record
|
||||
* The GridRecord containing the data to add
|
||||
* @param assembledRecord
|
||||
|
@ -216,7 +217,7 @@ public class EnsembleGridAssembler implements IDecoderPostProcessor {
|
|||
pGrid.setxOffset((nx * modIndex) - modIndex);
|
||||
pGrid.setyOffset(0);
|
||||
assembledRecord.addExtraAttribute(PartialGrid.KEY, pGrid);
|
||||
assembledRecord.setMessageData(recordToAssemble.getMessageData());
|
||||
assembledRecord.setMessageData(getMessageData(recordToAssemble));
|
||||
|
||||
return checkWorldWrap(assembledRecord);
|
||||
}
|
||||
|
@ -225,7 +226,7 @@ public class EnsembleGridAssembler implements IDecoderPostProcessor {
|
|||
* Checks if assembledRecord's partial grid has extra columns that wrap
|
||||
* around. This is due to partial grids having 1 column of overlap between
|
||||
* each partial grid.
|
||||
*
|
||||
*
|
||||
* @param assembledRecord
|
||||
* @return
|
||||
*/
|
||||
|
@ -278,5 +279,4 @@ public class EnsembleGridAssembler implements IDecoderPostProcessor {
|
|||
|
||||
return Util.resizeDataTo1D(rval, ny, nx);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -43,13 +43,14 @@ import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
|||
* Mar 26, 2013 1821 bsteffen Optimize FFG version query.
|
||||
* Oct 15, 2013 2473 bsteffen Remove deprecated method calls.
|
||||
* Apr 25, 2014 2060 njensen Remove dependency on grid dataURI column
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class FFGGribPostProcessor implements IDecoderPostProcessor {
|
||||
public class FFGGribPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
|
|
|
@ -1,226 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridConstants;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.common.dataquery.db.QueryParam.QueryOperand;
|
||||
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
|
||||
import com.raytheon.uf.common.parameter.Parameter;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.common.time.TimeRange;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
||||
import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
||||
|
||||
/**
|
||||
* Used to generate 6hr record from 12hr intervals.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Apr 25, 2011 rgeorge Initial creation
|
||||
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
||||
* Oct 15, 2013 2473 bsteffen Remove deprecated method calls.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rgeorge
|
||||
* @version 1.0
|
||||
*/
|
||||
public class GFSProcessor extends SixHrPrecipGridProcessor {
|
||||
private static final int SECONDS_IN_12_HRS = 43200;
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
// Post process the data if this is a Total Precipitation grid
|
||||
if (record.getParameter().getAbbreviation().equals("TP12hr")
|
||||
&& ((record.getDataTime().getFcstTime() / 3600) > 180)) {
|
||||
return super.process(record);
|
||||
}
|
||||
return new GridRecord[] { record };
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the 6 hour accumulated grid from the run accumulated
|
||||
* precipitation grids. This function will look in the inventory and
|
||||
* generate any 6 hr grids that can be generated.
|
||||
*
|
||||
* @param record
|
||||
* The grib record for which to generate the 6 hour accumulated
|
||||
* precipitation grid
|
||||
* @return The generated 6-hr precipitation grids
|
||||
* @throws GribException
|
||||
*/
|
||||
@Override
|
||||
protected synchronized GridRecord[] generate6hrPrecipGrids(GridRecord record)
|
||||
throws GribException {
|
||||
List<GridRecord> generated6hrPrecips = new ArrayList<GridRecord>();
|
||||
// Get all 6hr records 180Hrs and greater
|
||||
List<GridRecord> precipInventory = getPrecipInventory(record
|
||||
.getDataTime().getRefTime());
|
||||
List<GridRecord> generatedRecords = new ArrayList<GridRecord>();
|
||||
// convert current record to 6hr and add it
|
||||
GridRecord transformed = transForm12to6(record);
|
||||
generated6hrPrecips.add(transformed);
|
||||
precipInventory.add(transformed);
|
||||
Comparator<GridRecord> comparator = new Comparator<GridRecord>() {
|
||||
@Override
|
||||
public int compare(GridRecord o1, GridRecord o2) {
|
||||
int retValue = 0;
|
||||
if (o1 != o2) {
|
||||
retValue = Double.compare(o1.getDataTime().getFcstTime(),
|
||||
o2.getDataTime().getFcstTime());
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
};
|
||||
|
||||
Collections.sort(precipInventory, comparator);
|
||||
// loop through set, find twelve hour gaps and create new 6hr records.
|
||||
for (int i = 0; i < (precipInventory.size() - 1); i++) {
|
||||
GridRecord sequence1Record = precipInventory.get(i);
|
||||
GridRecord sequence2Record = precipInventory.get(i + 1);
|
||||
if (sequence1Record.getDataTime().getFcstTime() == (sequence2Record
|
||||
.getDataTime().getFcstTime() - SECONDS_IN_12_HRS)) {
|
||||
// we have a 12Hr gap
|
||||
generated6hrPrecips.add(calculate6hrPrecip(sequence1Record,
|
||||
sequence2Record));
|
||||
}
|
||||
}
|
||||
for (GridRecord newRecord : generated6hrPrecips) {
|
||||
// Add the generated grid to the current inventory
|
||||
if (newRecord != null) {
|
||||
generatedRecords.add(newRecord);
|
||||
}
|
||||
}
|
||||
return generatedRecords.toArray(new GridRecord[] {});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<GridRecord> getPrecipInventory(Date refTime)
|
||||
throws GribException {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating grib dao!", e);
|
||||
}
|
||||
DatabaseQuery query = new DatabaseQuery(GridRecord.class);
|
||||
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, "TP6hr",
|
||||
QueryOperand.IN);
|
||||
query.addQueryParam(GridConstants.DATASET_ID, "GFS213");
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addQueryParam("dataTime.fcstTime", 648000,
|
||||
QueryOperand.GREATERTHANEQUALS);
|
||||
query.addOrder("dataTime.fcstTime", true);
|
||||
try {
|
||||
return (List<GridRecord>) dao.queryByCriteria(query);
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException(
|
||||
"Error getting Precip inventory for ECMWF!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private GridRecord transForm12to6(GridRecord currentRecord)
|
||||
throws GribException {
|
||||
|
||||
// Clone the current record and set the ID to 0 so Hibernate will
|
||||
// recognize it as a new record
|
||||
GridRecord tp6hrRecord = new GridRecord(currentRecord);
|
||||
tp6hrRecord.setId(0);
|
||||
if (currentRecord.getMessageData() == null) {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
currentRecord.setMessageData(((FloatDataRecord) dao
|
||||
.getHDF5Data(currentRecord, -1)[0]).getFloatData());
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error populating grib data!", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the data to the new record so the data from the original record
|
||||
// does not get modified
|
||||
float[] currentData = (float[]) currentRecord.getMessageData();
|
||||
currentRecord.setMessageData(currentData);
|
||||
float[] newData = new float[currentData.length];
|
||||
System.arraycopy(currentData, 0, newData, 0, currentData.length);
|
||||
tp6hrRecord.setMessageData(newData);
|
||||
|
||||
// Assign the new parameter abbreviation and cache it if necessary
|
||||
Parameter param = new Parameter("TP6hr", "Precip Accum 6 hr",
|
||||
currentRecord.getParameter().getUnit());
|
||||
tp6hrRecord.setParameter(param);
|
||||
tp6hrRecord.getInfo().setId(null);
|
||||
// Change the data time to include the 6-hr time range
|
||||
super.modifyDataTime(tp6hrRecord);
|
||||
return tp6hrRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
protected void calculatePrecipValues(float[] inventoryData, float[] newData) {
|
||||
for (int i = 0; i < inventoryData.length; i++) {
|
||||
newData[i] = (newData[i] + inventoryData[i]) / 2;
|
||||
if (newData[i] < 0) {
|
||||
newData[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void modifyDataTime(GridRecord record) {
|
||||
|
||||
Calendar refTime = record.getDataTime().getRefTimeAsCalendar();
|
||||
int fcstTime = record.getDataTime().getFcstTime();
|
||||
|
||||
// Calculate the start time by subtracting 6 hours from the reference
|
||||
// time + forecast time
|
||||
Calendar startTime = (Calendar) refTime.clone();
|
||||
startTime.add(Calendar.SECOND, fcstTime - SECONDS_IN_6_HRS);
|
||||
|
||||
// Calculate the end time by adding the reference time + forecast time
|
||||
Calendar endTime = (Calendar) refTime.clone();
|
||||
endTime.add(Calendar.SECOND, fcstTime);
|
||||
TimeRange validPeriod = new TimeRange(startTime, endTime);
|
||||
DataTime newDataTime = new DataTime(refTime, fcstTime
|
||||
- SECONDS_IN_6_HRS, validPeriod);
|
||||
|
||||
// Reset the datauri since the datauri contains the DataTime
|
||||
record.setDataTime(newDataTime);
|
||||
record.setDataURI(null);
|
||||
}
|
||||
}
|
|
@ -24,15 +24,22 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
import org.apache.camel.Headers;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.decoderpostprocessors.DecoderPostProcessor.PostProcessorType;
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.edex.plugin.grib.util.GribModelLookup;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.annotations.DataURIUtil;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.common.dataplugin.message.DataURINotificationMessage;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
||||
|
@ -57,6 +64,8 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
* Oct 15, 2013 2473 bsteffen Rewrite deprecated and unused code.
|
||||
* Sep 24, 2015 3731 nabowle Allow pre-registering shortnames and
|
||||
* require fully qualified names otherwise.
|
||||
* Oct 07, 2015 3756 nabowle Add separate post-processing after the
|
||||
* decoded record is persisted.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -64,6 +73,8 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
* @version 1
|
||||
*/
|
||||
public class GribPostProcessor {
|
||||
private static final GridRecord[] EMPTY_ARR = new GridRecord[] {};
|
||||
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(GribPostProcessor.class);
|
||||
|
||||
|
@ -71,7 +82,7 @@ public class GribPostProcessor {
|
|||
private static GribPostProcessor instance;
|
||||
|
||||
/** The map containing the currently registered grib post processors */
|
||||
private Map<String, List<IDecoderPostProcessor>> processorMap;
|
||||
private Map<String, List<DecoderPostProcessor>> processorMap;
|
||||
|
||||
private Map<String, String> knownProcessors = new HashMap<>();
|
||||
|
||||
|
@ -110,7 +121,7 @@ public class GribPostProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
List<IDecoderPostProcessor> processors;
|
||||
List<DecoderPostProcessor> processors;
|
||||
GridRecord[] results = null;
|
||||
List<GridRecord> additionalGrids = null;
|
||||
for (int i = 0; i < records.length; i++) {
|
||||
|
@ -118,9 +129,11 @@ public class GribPostProcessor {
|
|||
// which post processing is necessary
|
||||
processors = processorMap.get(records[i].getDatasetId());
|
||||
if (processors != null) {
|
||||
for (IDecoderPostProcessor processor : processors) {
|
||||
for (DecoderPostProcessor processor : processors) {
|
||||
// Post processing is not necessary, so we continue
|
||||
if (processor == null) {
|
||||
if (processor == null
|
||||
|| PostProcessorType.POST_PERSIST.equals(processor
|
||||
.getType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -147,12 +160,83 @@ public class GribPostProcessor {
|
|||
for (int i = 0; i < records.length; i++) {
|
||||
additionalGrids.add(records[i]);
|
||||
}
|
||||
return additionalGrids.toArray(new GridRecord[] {});
|
||||
return additionalGrids.toArray(EMPTY_ARR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the IDecoderPostProcessor classes for the supplied
|
||||
* Processes the GridRecords to determine if they need post processing
|
||||
*
|
||||
* @param notif
|
||||
* A notification of datauri's that have been persisted.
|
||||
* @return Only grid records created by the post processors. The records
|
||||
* matching the uri's will not be returned.
|
||||
* @throws GribException
|
||||
*/
|
||||
public GridRecord[] processPersisted(DataURINotificationMessage notif,
|
||||
@Headers
|
||||
Map<String, Object> headers) throws GribException {
|
||||
headers.put("dequeueTime", System.currentTimeMillis());
|
||||
String[] dataURIs = notif.getDataURIs();
|
||||
if (dataURIs == null || dataURIs.length == 0) {
|
||||
return EMPTY_ARR;
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
if (this.processorMap == null) {
|
||||
initProcessorMap();
|
||||
}
|
||||
}
|
||||
|
||||
List<DecoderPostProcessor> processors;
|
||||
GridRecord[] recordResults;
|
||||
Set<GridRecord> newGrids = new HashSet<>();
|
||||
GridRecord record;
|
||||
|
||||
for (String uri : dataURIs) {
|
||||
try {
|
||||
record = (GridRecord) DataURIUtil.createPluginDataObject(uri);
|
||||
} catch (PluginException e) {
|
||||
throw new GribException(
|
||||
"Could not create plugin data object for " + uri, e);
|
||||
}
|
||||
|
||||
processors = processorMap.get(record.getDatasetId());
|
||||
if (processors != null) {
|
||||
for (DecoderPostProcessor processor : processors) {
|
||||
if (processor == null
|
||||
|| PostProcessorType.PRE_PERSIST.equals(processor
|
||||
.getType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
recordResults = processor.process(record);
|
||||
|
||||
if (recordResults != null) {
|
||||
for (GridRecord rec : recordResults) {
|
||||
if (!uri.equals(rec.getDataURI())) {
|
||||
newGrids.add(rec);
|
||||
} else {
|
||||
statusHandler
|
||||
.warn(uri
|
||||
+ " will not be re-persisted to prevent an infinite post-processing loop. "
|
||||
+ processor.getClass()
|
||||
.getName()
|
||||
+ " should be of type "
|
||||
+ PostProcessorType.PRE_PERSIST
|
||||
.name()
|
||||
+ " or should not include the post-processed record in the results.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newGrids.toArray(EMPTY_ARR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the DecoderPostProcessor classes for the supplied
|
||||
* fully-qualified classnames.
|
||||
*
|
||||
* @param fqClassNames
|
||||
|
@ -160,7 +244,7 @@ public class GribPostProcessor {
|
|||
*/
|
||||
public synchronized void register(String... fqClassNames) {
|
||||
String retClass;
|
||||
IDecoderPostProcessor newProc;
|
||||
DecoderPostProcessor newProc;
|
||||
Object newObj;
|
||||
for (String className : fqClassNames) {
|
||||
if (className == null || className.trim().isEmpty()) {
|
||||
|
@ -177,22 +261,22 @@ public class GribPostProcessor {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!(newObj instanceof IDecoderPostProcessor)) {
|
||||
if (!(newObj instanceof DecoderPostProcessor)) {
|
||||
statusHandler.warn(className
|
||||
+ " is not an IDecoderPostProcessor");
|
||||
+ " is not an DecoderPostProcessor");
|
||||
continue;
|
||||
}
|
||||
|
||||
newProc = (IDecoderPostProcessor) newObj;
|
||||
newProc = (DecoderPostProcessor) newObj;
|
||||
statusHandler.debug("Registering grib post processor for "
|
||||
+ className);
|
||||
retClass = knownProcessors.put(newProc.getClass()
|
||||
.getSimpleName(), className);
|
||||
retClass = knownProcessors.put(newProc.getClass().getSimpleName(),
|
||||
className);
|
||||
|
||||
/* Warn if two registered classes share the same simple class name. */
|
||||
if (retClass != null && !retClass.equals(className)) {
|
||||
statusHandler.warn(retClass
|
||||
+ " has been replaced by " + className);
|
||||
statusHandler.warn(retClass + " has been replaced by "
|
||||
+ className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +305,7 @@ public class GribPostProcessor {
|
|||
statusHandler.info(String.format("Using postProcessorFile [%s]",
|
||||
processorFile));
|
||||
|
||||
Map<String, List<IDecoderPostProcessor>> newMap = new HashMap<>();
|
||||
Map<String, List<DecoderPostProcessor>> newMap = new HashMap<>();
|
||||
|
||||
/*
|
||||
* Iterate over post processed models. Determine which models apply
|
||||
|
@ -232,10 +316,10 @@ public class GribPostProcessor {
|
|||
for (PostProcessedModel ppModel : ppModelSet.getModels()) {
|
||||
for (String modelName : modelNames) {
|
||||
if (modelName.matches(ppModel.getModelName())) {
|
||||
List<IDecoderPostProcessor> processorInstances = newMap
|
||||
List<DecoderPostProcessor> processorInstances = newMap
|
||||
.get(modelName);
|
||||
if (processorInstances == null) {
|
||||
processorInstances = new ArrayList<IDecoderPostProcessor>();
|
||||
processorInstances = new ArrayList<DecoderPostProcessor>();
|
||||
newMap.put(modelName, processorInstances);
|
||||
}
|
||||
|
||||
|
@ -249,7 +333,7 @@ public class GribPostProcessor {
|
|||
|
||||
try {
|
||||
processorInstances
|
||||
.add((IDecoderPostProcessor) Class
|
||||
.add((DecoderPostProcessor) Class
|
||||
.forName(classToLoad)
|
||||
.newInstance());
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -28,19 +28,20 @@ import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
|||
* This post processor currently looks for precipitation probability grids and
|
||||
* multiplies the data values by 100 to get an actual percentage (values 0-100)
|
||||
* instead of a decimal value (0-1)
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 6/11/2015 4542 bphillip Initial creation
|
||||
*
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1.0
|
||||
*/
|
||||
public class HPCqpfPostProcessor implements IDecoderPostProcessor {
|
||||
public class HPCqpfPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
/** Parameter abbreviation patter for perecent probability grids */
|
||||
private static final String PCT_PROB_PATTERN = "ProbTP\\dp\\d{2}in\\d{1,2}hr";
|
||||
|
@ -51,7 +52,7 @@ public class HPCqpfPostProcessor implements IDecoderPostProcessor {
|
|||
// Check to see if this is a grid we are looking for
|
||||
if (parameterAbbreviation.matches(PCT_PROB_PATTERN)) {
|
||||
// If so, multiply the data by 100 to obtain a percent
|
||||
float[] data = (float[]) record.getMessageData();
|
||||
float[] data = getMessageData(record);
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (data[i] >= 0.0 && data[i] <= 1.0) {
|
||||
data[i] *= 100;
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -46,21 +46,22 @@ import com.vividsolutions.jts.geom.Geometry;
|
|||
|
||||
/**
|
||||
* HWRF post processor implementation.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 10, 2015 4819 rferrel Initial Creation
|
||||
*
|
||||
* Sep 10, 2015 4819 rferrel Initial Creation
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1
|
||||
*/
|
||||
public class HWRFPostProcessor implements IDecoderPostProcessor {
|
||||
public class HWRFPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
/**
|
||||
* Format for datasetId prefix <model>-<dx><spacingUnit>-.
|
||||
|
@ -131,7 +132,7 @@ public class HWRFPostProcessor implements IDecoderPostProcessor {
|
|||
|
||||
/**
|
||||
* Add the count in ct's extrainfo to the dataset name prefix.
|
||||
*
|
||||
*
|
||||
* @param ct
|
||||
* @param datasetIdPrefix
|
||||
* @return datasetId
|
||||
|
@ -156,7 +157,7 @@ public class HWRFPostProcessor implements IDecoderPostProcessor {
|
|||
|
||||
/**
|
||||
* Find datasetId a result grid that has > 95% intersection with the record.
|
||||
*
|
||||
*
|
||||
* @param record
|
||||
* @param result
|
||||
* @return datasetId or null when > 95% intersection not found
|
||||
|
@ -189,7 +190,7 @@ public class HWRFPostProcessor implements IDecoderPostProcessor {
|
|||
/**
|
||||
* While locked get datasetId for the record's grid info and update the grid
|
||||
* info list associated with dsIdPrefix.
|
||||
*
|
||||
*
|
||||
* @param record
|
||||
* @param datasetIdPrefix
|
||||
*/
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
|
||||
/**
|
||||
* Grib decoder post processor interface
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 8/30/10 5875 bphillip Initial Creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public interface IDecoderPostProcessor {
|
||||
|
||||
/**
|
||||
* Processes the provided record to see if it needs to be post processed
|
||||
*
|
||||
* @param record
|
||||
* The record to examine to determine if it needs to be post
|
||||
* processed
|
||||
* @return The array of grib records including any created during post
|
||||
* processing
|
||||
* @throws GribException
|
||||
*/
|
||||
public GridRecord[] process(GridRecord record) throws GribException;
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -28,23 +28,24 @@ import com.raytheon.uf.common.parameter.Parameter;
|
|||
|
||||
/**
|
||||
* Adjusts the LAPS Grib data to have to correct level information
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Apr 07, 2011 6619 bphillip Initial creation
|
||||
* Oct 15, 2013 2473 bsteffen Remove deprecated method calls.
|
||||
* Sep 09, 2014 3356 njensen Remove CommunicationException
|
||||
*
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1.0
|
||||
*/
|
||||
public class LapsPostProcessor implements IDecoderPostProcessor {
|
||||
public class LapsPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
private static final String FHAG = "FHAG";
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -37,6 +37,7 @@ import com.raytheon.uf.common.parameter.Parameter;
|
|||
* ------------- -------- ----------- --------------------------
|
||||
* Aug 18, 2011 bphillip Initial creation
|
||||
* Oct 15, 2013 2473 bsteffen Remove deprecated method calls.
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
|
@ -45,7 +46,7 @@ import com.raytheon.uf.common.parameter.Parameter;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class MSASPostProcessor implements IDecoderPostProcessor {
|
||||
public class MSASPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
private static final String TSLSA = "TSLSA";
|
||||
|
||||
|
@ -65,7 +66,7 @@ public class MSASPostProcessor implements IDecoderPostProcessor {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.edex.plugin.grib.decoderpostprocessors.IDecoderPostProcessor
|
||||
* #process(com.raytheon.uf.common.dataplugin.grib.GridRecord)
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridConstants;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
|
||||
import com.raytheon.uf.common.parameter.Parameter;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.common.time.TimeRange;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
||||
import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
||||
|
||||
/**
|
||||
* Post processor for the NAM80 (ETA) model. This post processor generates the
|
||||
* missing 6 hour total and convective precipitation grids.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Nov 17, 2011 bphillip Initial creation
|
||||
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
||||
* Oct 15, 2013 2473 bsteffen Remove deprecated method calls.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class Nam80PostProcessor implements IDecoderPostProcessor {
|
||||
|
||||
/** The number of seconds in 6 hours */
|
||||
private static final int SECONDS_IN_6_HRS = 21600;
|
||||
|
||||
/** Parameter abbreviation for 12 hr total precipitation accumulation */
|
||||
private static final String TP_12HR = "TP12hr";
|
||||
|
||||
/** Parameter abbreviation for 6 hr total precipitation accumulation */
|
||||
private static final String TP_6HR = "TP6hr";
|
||||
|
||||
/** Parameter abbreviation for 12 hr convective precipitation accumulation */
|
||||
private static final String CP_12HR = "CP12hr";
|
||||
|
||||
/** Parameter abbreviation for 6 hr convective precipitation accumulation */
|
||||
private static final String CP_6HR = "CP6hr";
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.edex.plugin.grib.decoderpostprocessors.IDecoderPostProcessor
|
||||
* #process(com.raytheon.uf.common.dataplugin.grib.GridRecord)
|
||||
*/
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
|
||||
/*
|
||||
* Determine if this record is a 6 or 12 hour total precipitation
|
||||
* accumulation grid
|
||||
*/
|
||||
if (record.getParameter().getAbbreviation().equals(TP_12HR)) {
|
||||
return generate6HrGrids(record, false, TP_6HR, TP_12HR);
|
||||
} else if (record.getParameter().getAbbreviation().equals(TP_6HR)) {
|
||||
return generate6HrGrids(record, true, TP_6HR, TP_12HR);
|
||||
} else if (record.getParameter().getAbbreviation().equals(CP_12HR)) {
|
||||
return generate6HrGrids(record, false, CP_6HR, CP_12HR);
|
||||
} else if (record.getParameter().getAbbreviation().equals(CP_6HR)) {
|
||||
return generate6HrGrids(record, true, CP_6HR, CP_12HR);
|
||||
}
|
||||
|
||||
return new GridRecord[] { record };
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private GridRecord[] generate6HrGrids(GridRecord currentRecord,
|
||||
boolean sixHr, String parameter6hr, String parameter12hr)
|
||||
throws GribException {
|
||||
// The 12 hr accumulation grid to use in the calculations
|
||||
GridRecord tp12record = null;
|
||||
|
||||
// The 6 hr accumulation grid to use in the calculations
|
||||
GridRecord tp6record = null;
|
||||
Date refTime = currentRecord.getDataTime().getRefTime();
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating Grib Dao!", e);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the current record is a 6 hr accumulation grid, get the 12 hr grid
|
||||
* and vice versa
|
||||
*/
|
||||
DatabaseQuery dbQuery = new DatabaseQuery(GridRecord.class);
|
||||
dbQuery.addQueryParam(GridConstants.DATASET_ID, "ETA");
|
||||
dbQuery.addQueryParam("dataTime.refTime", refTime);
|
||||
if (sixHr) {
|
||||
tp6record = currentRecord;
|
||||
dbQuery.addQueryParam(GridConstants.PARAMETER_ABBREVIATION,
|
||||
parameter12hr);
|
||||
dbQuery.addQueryParam("dataTime.fcstTime", currentRecord
|
||||
.getDataTime().getFcstTime() + SECONDS_IN_6_HRS);
|
||||
} else {
|
||||
tp12record = currentRecord;
|
||||
dbQuery.addQueryParam(GridConstants.PARAMETER_ABBREVIATION,
|
||||
parameter6hr);
|
||||
dbQuery.addQueryParam("dataTime.fcstTime", currentRecord
|
||||
.getDataTime().getFcstTime() - SECONDS_IN_6_HRS);
|
||||
}
|
||||
try {
|
||||
List<GridRecord> results = (List<GridRecord>) dao
|
||||
.queryByCriteria(dbQuery);
|
||||
if (results.isEmpty()) {
|
||||
return new GridRecord[] { currentRecord };
|
||||
}
|
||||
if (sixHr) {
|
||||
tp12record = results.get(0);
|
||||
} else {
|
||||
tp6record = results.get(0);
|
||||
}
|
||||
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException("Error querying for 12 hr precip records!",
|
||||
e);
|
||||
}
|
||||
|
||||
Set<GridRecord> retVal = new HashSet<GridRecord>();
|
||||
retVal.add(currentRecord);
|
||||
retVal.add(generateGrid(tp12record, tp6record, dao, parameter6hr));
|
||||
|
||||
return retVal.toArray(new GridRecord[] {});
|
||||
}
|
||||
|
||||
private GridRecord generateGrid(GridRecord tp12HrRecord,
|
||||
GridRecord tp6HrRecord, GridDao dao, String parameter)
|
||||
throws GribException {
|
||||
|
||||
GridRecord newRecord = new GridRecord();
|
||||
try {
|
||||
float[] newData = null;
|
||||
float[] tp6Data = null;
|
||||
if (tp12HrRecord.getMessageData() == null) {
|
||||
newData = ((FloatDataRecord) dao.getHDF5Data(tp12HrRecord, -1)[0])
|
||||
.getFloatData();
|
||||
} else {
|
||||
newData = (float[]) tp12HrRecord.getMessageData();
|
||||
}
|
||||
if (tp6HrRecord.getMessageData() == null) {
|
||||
tp6Data = ((FloatDataRecord) dao.getHDF5Data(tp6HrRecord, -1)[0])
|
||||
.getFloatData();
|
||||
} else {
|
||||
tp6Data = (float[]) tp6HrRecord.getMessageData();
|
||||
}
|
||||
for (int i = 0; i < newData.length; i++) {
|
||||
newData[i] -= tp6Data[i];
|
||||
}
|
||||
newRecord.setMessageData(newData);
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error retrieving precipitation data", e);
|
||||
}
|
||||
|
||||
newRecord.setLocation(tp6HrRecord.getLocation());
|
||||
newRecord.setDatasetId(tp6HrRecord.getDatasetId());
|
||||
newRecord.setLevel(tp6HrRecord.getLevel());
|
||||
Parameter param = new Parameter(parameter, tp6HrRecord.getParameter()
|
||||
.getUnit());
|
||||
newRecord.setParameter(param);
|
||||
Calendar refTime = tp12HrRecord.getDataTime().getRefTimeAsCalendar();
|
||||
Date start = new Date(tp12HrRecord.getDataTime().getValidPeriod()
|
||||
.getEnd().getTime()
|
||||
- (SECONDS_IN_6_HRS * 1000));
|
||||
|
||||
DataTime newDataTime = new DataTime(refTime, tp12HrRecord.getDataTime()
|
||||
.getFcstTime(), new TimeRange(start, tp12HrRecord.getDataTime()
|
||||
.getValidPeriod().getEnd()));
|
||||
|
||||
// Reset the datauri since the datauri contains the DataTime
|
||||
newRecord.setDataTime(newDataTime);
|
||||
newRecord.getInfo().setId(null);
|
||||
newRecord.setDataURI(null);
|
||||
newRecord.setOverwriteAllowed(true);
|
||||
return newRecord;
|
||||
}
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -34,18 +34,18 @@ import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 11/12/10 4524 bphillip Initial Creation
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class OverwriteGribPostProcessor implements IDecoderPostProcessor {
|
||||
public class OverwriteGribPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
record.setOverwriteAllowed(true);
|
||||
return new GridRecord[] { record };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -30,23 +30,24 @@ import com.raytheon.uf.common.time.TimeRange;
|
|||
/**
|
||||
* Grib post processor implementation correct the total cloud cover parameter in
|
||||
* the RTMA grib model
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Feb 01, 2011 6320 bphillip Initial Creation
|
||||
* Oct 15, 2013 2473 bsteffen Remove deprecated method calls.
|
||||
*
|
||||
*
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class RTMAGribPostProcessor implements IDecoderPostProcessor {
|
||||
public class RTMAGribPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -26,21 +26,22 @@ import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
|||
/**
|
||||
* Grib post processor implementation to eliminate 2-3hr duration grids from the
|
||||
* RUC130 model
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 9/9/10 #4419 bphillip Initial Creation
|
||||
*
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author bphillip
|
||||
* @version 1
|
||||
*/
|
||||
public class RUC130GribPostProcessor implements IDecoderPostProcessor {
|
||||
public class RUC130GribPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -34,13 +34,13 @@ import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* 1/24/2012 DR 14263 M. Porricelli Initial Creation
|
||||
*
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
* </pre>
|
||||
*
|
||||
* @author porricel
|
||||
* @version 1
|
||||
*/
|
||||
public class RUC236GribPostProcessor implements IDecoderPostProcessor {
|
||||
public class RUC236GribPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
|
|
|
@ -1,214 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
|
||||
import com.raytheon.uf.common.parameter.Parameter;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.common.time.TimeRange;
|
||||
import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
||||
|
||||
/**
|
||||
* Abstract class to generate 6hr records
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Apr 25, 2011 rgeorge Initial creation
|
||||
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
||||
* Oct 15, 2013 2473 bsteffen Removed deprecated and unused code.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rgeorge
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class SixHrPrecipGridProcessor implements IDecoderPostProcessor {
|
||||
|
||||
/** The number of seconds in 6 hours */
|
||||
protected static final int SECONDS_IN_6_HRS = 21600;
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
|
||||
// Post process the data if this is a Total Precipitation grid
|
||||
|
||||
GridRecord[] newRecords = generate6hrPrecipGrids(record);
|
||||
GridRecord[] retVal = new GridRecord[newRecords.length + 1];
|
||||
retVal[0] = record;
|
||||
for (int i = 1; i < retVal.length; i++) {
|
||||
retVal[i] = newRecords[i - 1];
|
||||
}
|
||||
return retVal;
|
||||
|
||||
}
|
||||
|
||||
protected abstract GridRecord[] generate6hrPrecipGrids(GridRecord record)
|
||||
throws GribException;
|
||||
|
||||
/**
|
||||
* Generates the 6hr precipitation grid
|
||||
*
|
||||
* @param record
|
||||
* The current record to clone and modify to produce the new 6hr
|
||||
* grid
|
||||
* @param precipInventory
|
||||
* The current run accumulated grid inventory
|
||||
* @return The generated 6hr precipitation grid
|
||||
* @throws GribException
|
||||
*/
|
||||
protected List<GridRecord> generate6hrPrecip(GridRecord record,
|
||||
List<GridRecord> precipInventory)
|
||||
throws GribException {
|
||||
List<GridRecord> tp6hrRecords = new ArrayList<GridRecord>();
|
||||
int currentFcstTime = record.getDataTime().getFcstTime();
|
||||
|
||||
// If this is the first grid (the 6 hr grid), the 6hr precip
|
||||
// accumulation is the same as the 6hr run accumulated grid
|
||||
if (currentFcstTime == SECONDS_IN_6_HRS) {
|
||||
tp6hrRecords.add(calculate6hrPrecip(null, record));
|
||||
}
|
||||
// If this is not the first grid, generate the new grid using the
|
||||
// previous grid
|
||||
else {
|
||||
for (GridRecord rec : precipInventory) {
|
||||
if (rec.getDataTime().getFcstTime() == (currentFcstTime - SECONDS_IN_6_HRS)) {
|
||||
tp6hrRecords.add(calculate6hrPrecip(rec, record));
|
||||
}
|
||||
}
|
||||
}
|
||||
return tp6hrRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the 6hr precipitation grid from the current grid and the
|
||||
* previous grid
|
||||
*
|
||||
* @param inventoryRecord
|
||||
* The previous grid from the inventory
|
||||
* @param currentRecord
|
||||
* The current grid
|
||||
* @return The generated 6hr precipitation grid
|
||||
* @throws GribException
|
||||
*/
|
||||
protected GridRecord calculate6hrPrecip(GridRecord inventoryRecord,
|
||||
GridRecord currentRecord) throws GribException {
|
||||
|
||||
// Clone the current record and set the ID to 0 so Hibernate will
|
||||
// recognize it as a new record
|
||||
GridRecord tp6hrRecord = new GridRecord(currentRecord);
|
||||
tp6hrRecord.setId(0);
|
||||
if (currentRecord.getMessageData() == null) {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
currentRecord.setMessageData(((FloatDataRecord) dao
|
||||
.getHDF5Data(currentRecord, -1)[0]).getFloatData());
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error populating grib data!", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the data to the new record so the data from the original record
|
||||
// does not get modified
|
||||
float[] currentData = (float[]) currentRecord.getMessageData();
|
||||
currentRecord.setMessageData(currentData);
|
||||
float[] newData = new float[currentData.length];
|
||||
System.arraycopy(currentData, 0, newData, 0, currentData.length);
|
||||
tp6hrRecord.setMessageData(newData);
|
||||
|
||||
// Assign the new parameter abbreviation and cache it if necessary
|
||||
Parameter param = new Parameter("TP6hr", "Precip Accum 6 hr",
|
||||
currentRecord.getParameter().getUnit());
|
||||
tp6hrRecord.setParameter(param);
|
||||
tp6hrRecord.getInfo().setId(null);
|
||||
// Change the data time to include the 6-hr time range
|
||||
modifyDataTime(tp6hrRecord);
|
||||
|
||||
// Calculate the new data values
|
||||
if (inventoryRecord != null) {
|
||||
if (inventoryRecord.getMessageData() == null) {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
inventoryRecord
|
||||
.setMessageData(((FloatDataRecord) dao.getHDF5Data(
|
||||
inventoryRecord, 0)[0]).getFloatData());
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error populating grib data!", e);
|
||||
}
|
||||
}
|
||||
calculatePrecipValues((float[]) inventoryRecord.getMessageData(),
|
||||
(float[]) tp6hrRecord.getMessageData());
|
||||
}
|
||||
return tp6hrRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the new data by subtracting the previous inventory data from
|
||||
* the current data
|
||||
*
|
||||
* @param inventoryData
|
||||
* The data from the previous precipitation record
|
||||
* @param newData
|
||||
* The data from the current precipitation record
|
||||
*/
|
||||
protected abstract void calculatePrecipValues(float[] messageData,
|
||||
float[] messageData2);
|
||||
|
||||
/**
|
||||
* Modifies the DataTime of the provided record to include a 6hr time range
|
||||
*
|
||||
* @param record
|
||||
* The record to modify the datatime for
|
||||
*/
|
||||
protected void modifyDataTime(GridRecord record) {
|
||||
|
||||
Calendar refTime = record.getDataTime().getRefTimeAsCalendar();
|
||||
int fcstTime = record.getDataTime().getFcstTime();
|
||||
|
||||
// Calculate the start time by subtracting 6 hours from the reference
|
||||
// time + forecast time
|
||||
Calendar startTime = (Calendar) refTime.clone();
|
||||
startTime.add(Calendar.SECOND, fcstTime - SECONDS_IN_6_HRS);
|
||||
|
||||
// Calculate the end time by adding the reference time + forecast time
|
||||
Calendar endTime = (Calendar) refTime.clone();
|
||||
endTime.add(Calendar.SECOND, fcstTime);
|
||||
TimeRange validPeriod = new TimeRange(startTime, endTime);
|
||||
DataTime newDataTime = new DataTime(refTime, fcstTime, validPeriod);
|
||||
|
||||
// Reset the datauri since the datauri contains the DataTime
|
||||
record.setDataTime(newDataTime);
|
||||
record.setDataURI(null);
|
||||
}
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -45,31 +45,32 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* Adjusts temperature values that are mislabled as Celsius or Kelvin when they
|
||||
* actually represent the other one. Loads a list of parameters and thresholds
|
||||
* from a localization file. Assumes that all values above the threshold for a
|
||||
* parameter are in Kelvin and will convert if the declared unit is Celsius.
|
||||
* Values below the threshold are assumed to be in Celsius and will be converted
|
||||
* if the declared unit is Kelvin
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Mar 28, 2010 2874 bsteffen Initial creation
|
||||
* Apr 25, 2014 2060 njensen Use JAXB instead of JAXBManager
|
||||
*
|
||||
*
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class TemperatureCorrectionPostProcessor implements
|
||||
IDecoderPostProcessor, ILocalizationFileObserver {
|
||||
public class TemperatureCorrectionPostProcessor extends DecoderPostProcessor
|
||||
implements ILocalizationFileObserver {
|
||||
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(TemperatureCorrectionPostProcessor.class);
|
||||
|
@ -208,5 +209,4 @@ public class TemperatureCorrectionPostProcessor implements
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
|
@ -34,7 +34,11 @@ import com.raytheon.uf.common.time.TimeRange;
|
|||
import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
||||
|
||||
/**
|
||||
* Abstract class to generate 3hr records
|
||||
* Abstract class to generate 3hr records.
|
||||
*
|
||||
* Note: This class has been replaced by PrecipAccumPostProcessor and only
|
||||
* remains for
|
||||
* gov.noaa.nws.crh.edex.grib.decoderpostprocessor.GFS20PostProcessor
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
|
@ -46,14 +50,15 @@ import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
|||
* Jan 24, 2012 14299 M. Porricelli Initial creation
|
||||
* Aug 30, 2013 2298 rjpeter Make getPluginName abstract
|
||||
* Oct 15, 2013 2473 bsteffen Removed deprecated and unused code.
|
||||
* Oct 07, 2015 3756 nabowle Extends DecoderPostProcessor.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author porricel
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class ThreeHrPrecipGridProcessor implements
|
||||
IDecoderPostProcessor {
|
||||
public abstract class ThreeHrPrecipGridProcessor extends
|
||||
DecoderPostProcessor {
|
||||
|
||||
/** The number of seconds in 3 hours */
|
||||
protected static final int SECONDS_IN_3_HRS = 10800;
|
||||
|
@ -78,7 +83,7 @@ public abstract class ThreeHrPrecipGridProcessor implements
|
|||
|
||||
/**
|
||||
* Generates the 3hr precipitation grid
|
||||
*
|
||||
*
|
||||
* @param record
|
||||
* The current record to clone and modify to produce the new 3hr
|
||||
* grid
|
||||
|
@ -113,7 +118,7 @@ public abstract class ThreeHrPrecipGridProcessor implements
|
|||
/**
|
||||
* Generates the 3hr precipitation grid from the current grid and the
|
||||
* previous grid
|
||||
*
|
||||
*
|
||||
* @param inventoryRecord
|
||||
* The previous grid from the inventory
|
||||
* @param currentRecord
|
||||
|
@ -178,7 +183,7 @@ public abstract class ThreeHrPrecipGridProcessor implements
|
|||
/**
|
||||
* Calculates the new data by subtracting the previous inventory data from
|
||||
* the current data
|
||||
*
|
||||
*
|
||||
* @param inventoryData
|
||||
* The data from the previous precipitation record
|
||||
* @param newData
|
||||
|
@ -189,7 +194,7 @@ public abstract class ThreeHrPrecipGridProcessor implements
|
|||
|
||||
/**
|
||||
* Modifies the DataTime of the provided record to include a 3hr time range
|
||||
*
|
||||
*
|
||||
* @param record
|
||||
* The record to modify the datatime for
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,228 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors.precipitation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
/**
|
||||
* Stores a list of models and a list of AccumulationCreationConfigs to apply
|
||||
* for those models.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 28, 2015 3756 nabowle Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public class AccumulationConfig {
|
||||
|
||||
@XmlElement(name = "model")
|
||||
private List<String> models;
|
||||
|
||||
@XmlElement(name = "create")
|
||||
private List<AccumulationCreationConfig> creations;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public AccumulationConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param models
|
||||
* The list of models to match.
|
||||
* @param creations
|
||||
* The list of accumulations to create.
|
||||
*/
|
||||
public AccumulationConfig(List<String> models,
|
||||
List<AccumulationCreationConfig> creations) {
|
||||
super();
|
||||
this.models = models;
|
||||
this.creations = creations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the models
|
||||
*/
|
||||
public List<String> getModels() {
|
||||
return models;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param models
|
||||
* the models to set
|
||||
*/
|
||||
public void setModels(List<String> models) {
|
||||
this.models = models;
|
||||
}
|
||||
|
||||
public boolean addModel(String model) {
|
||||
if (this.models == null) {
|
||||
this.models = new ArrayList<>();
|
||||
}
|
||||
return this.models.add(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the creations
|
||||
*/
|
||||
public List<AccumulationCreationConfig> getCreations() {
|
||||
return creations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param creations
|
||||
* the creations to set
|
||||
*/
|
||||
public void setCreations(List<AccumulationCreationConfig> creations) {
|
||||
this.creations = creations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to determine if this configuration matches a given
|
||||
* model.
|
||||
*
|
||||
* @param model
|
||||
* The model to check for.
|
||||
* @return True if the model matches one of the configured models, false
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean modelMatches(String model) {
|
||||
if (this.models == null) {
|
||||
return false;
|
||||
}
|
||||
for (String mod : this.models) {
|
||||
if (model.matches(mod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subset of creation configs whose minuend's or subtrahend's
|
||||
* parameter matches the given parameter, if any.
|
||||
*
|
||||
* @param parameter
|
||||
* The parameter to match.
|
||||
* @param matchMinuend
|
||||
* If true, parameter will be matched to the minuends'
|
||||
* parameters. If false, it will be match to the subtrahends'
|
||||
* parameters.
|
||||
* @return the subset of creation configs whose minuend's or subtrahend's
|
||||
* parameter matches the given parameter, if any. An empty list is
|
||||
* returned if no matches are found.
|
||||
*/
|
||||
public List<AccumulationCreationConfig> getCreations(String parameter,
|
||||
boolean matchMinuend) {
|
||||
List<AccumulationCreationConfig> matchedCreations = new ArrayList<>();
|
||||
|
||||
if (this.creations != null) {
|
||||
String param;
|
||||
for (AccumulationCreationConfig creation : this.creations) {
|
||||
param = matchMinuend ? creation.getMinuendParam() : creation
|
||||
.getSubtrahendParam();
|
||||
if (param.equals(parameter)) {
|
||||
matchedCreations.add(creation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matchedCreations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the list of creations of this config with the creations of the
|
||||
* other config. If this config already contains a creation, the duplicate
|
||||
* will not be added into this config.
|
||||
*
|
||||
* @param otherConfig
|
||||
* The accumulation config that's creations will be merged into
|
||||
* this config's creations.
|
||||
*/
|
||||
public void mergeCreations(AccumulationConfig otherConfig) {
|
||||
if (otherConfig == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.creations == null) {
|
||||
this.creations = otherConfig.getCreations();
|
||||
} else if (otherConfig.getCreations() != null) {
|
||||
boolean dupe;
|
||||
for (AccumulationCreationConfig toMerge : otherConfig
|
||||
.getCreations()) {
|
||||
if (toMerge == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dupe = false;
|
||||
for (AccumulationCreationConfig local : this.creations) {
|
||||
if (local.equals(toMerge)) {
|
||||
dupe = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dupe) {
|
||||
this.creations.add(toMerge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this AccumulationConfig has an equivalent collection of
|
||||
* models to the other AccumulationConfig. This collections are considered
|
||||
* equivalent if both are null or empty, or both contain the same models,
|
||||
* even if in different orders.
|
||||
*
|
||||
* This will not handle cases where a model-regex lists models in different
|
||||
* orders, e.g. {@code <model>GFS215|GFS217</model>} and
|
||||
* {@code <model>GFS217|GFS215</model>} are not considered equivalent,
|
||||
* though in practice they are.
|
||||
*/
|
||||
public boolean modelsEqual(AccumulationConfig other) {
|
||||
if (other == null) {
|
||||
return false;
|
||||
}
|
||||
if (other.getModels() == null || other.getModels().isEmpty()) {
|
||||
return this.models == null || this.getModels().isEmpty();
|
||||
}
|
||||
|
||||
return other.getModels().containsAll(this.getModels())
|
||||
&& this.getModels().containsAll(other.getModels());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors.precipitation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* Container for multiple AccumulationConfig instances.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 28, 2015 3756 nabowle Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public class AccumulationConfigs {
|
||||
|
||||
@XmlElement(name = "accumulation")
|
||||
private List<AccumulationConfig> accumulations;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public AccumulationConfigs() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param accums
|
||||
* The list of accumulations.
|
||||
*/
|
||||
public AccumulationConfigs(List<AccumulationConfig> accums) {
|
||||
this.accumulations = accums;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the accumulations
|
||||
*/
|
||||
public List<AccumulationConfig> getAccumulations() {
|
||||
return accumulations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param accumulations
|
||||
* the accumulations to set
|
||||
*/
|
||||
public void setAccumulations(List<AccumulationConfig> accumulations) {
|
||||
this.accumulations = accumulations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of {@link AccumulationConfig}s that match the given model, if
|
||||
* any. If no matches are found, an empty list is returned.
|
||||
*
|
||||
* @param model
|
||||
* The model to match.
|
||||
* @return A list containing all matching accumulation configs. If no
|
||||
* matches are found, and empty list is returned.
|
||||
*/
|
||||
public List<AccumulationConfig> getAccumulations(String model) {
|
||||
List<AccumulationConfig> accums = new ArrayList<>();
|
||||
for (AccumulationConfig accum : this.accumulations) {
|
||||
if (accum.modelMatches(model)) {
|
||||
accums.add(accum);
|
||||
}
|
||||
}
|
||||
return accums;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the AccumulationConfigs with this one. Any configs with equivalent
|
||||
* model lists will be merged, otherwise the config will be added into the
|
||||
* list of configs.
|
||||
*
|
||||
* @param configs
|
||||
* The configs to merge. If null, nothing is done.
|
||||
*/
|
||||
public void merge(AccumulationConfigs configs) {
|
||||
if (configs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean merged;
|
||||
for (AccumulationConfig toMerge : configs.getAccumulations()) {
|
||||
if (toMerge == null) {
|
||||
continue;
|
||||
}
|
||||
merged = false;
|
||||
for (AccumulationConfig local : this.accumulations) {
|
||||
if (local.modelsEqual(toMerge)) {
|
||||
local.mergeCreations(toMerge);
|
||||
merged = true;
|
||||
}
|
||||
}
|
||||
if (!merged) {
|
||||
this.accumulations.add(toMerge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors.precipitation;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
|
||||
/**
|
||||
* Describes the parameters used in an accumulation calculation.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 28, 2015 3756 nabowle Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public class AccumulationCreationConfig {
|
||||
|
||||
@XmlAttribute(required = true)
|
||||
private int forecastPeriodHours;
|
||||
|
||||
@XmlAttribute(required = true)
|
||||
private String accumulationParam;
|
||||
|
||||
@XmlAttribute(required = true)
|
||||
private String minuendParam;
|
||||
|
||||
@XmlAttribute(required = true)
|
||||
private String subtrahendParam;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public AccumulationCreationConfig() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
*
|
||||
* @param forecastPeriod
|
||||
* The forecast period in hours.
|
||||
* @param accumulation
|
||||
* The parameter to use for the calculated accumulation.
|
||||
* @param minuend
|
||||
* The parameter subtracted from in calculating accumulation.
|
||||
* @param subtrahend
|
||||
* The parameter being subtracted.
|
||||
*/
|
||||
public AccumulationCreationConfig(int forecastPeriod, String accumulation,
|
||||
String minuend, String subtrahend) {
|
||||
super();
|
||||
this.forecastPeriodHours = forecastPeriod;
|
||||
this.accumulationParam = accumulation;
|
||||
this.minuendParam = minuend;
|
||||
this.subtrahendParam = subtrahend;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the forecastPeriod
|
||||
*/
|
||||
public int getForecastPeriodHours() {
|
||||
return forecastPeriodHours;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param forecastPeriod
|
||||
* the forecastPeriod to set
|
||||
*/
|
||||
public void setForecastPeriodHours(int forecastPeriod) {
|
||||
this.forecastPeriodHours = forecastPeriod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the forecastPeriod in seconds.
|
||||
*/
|
||||
public int getForecastPeriodSeconds() {
|
||||
return forecastPeriodHours * TimeUtil.SECONDS_PER_HOUR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the accumulation
|
||||
*/
|
||||
public String getAccumulationParam() {
|
||||
return accumulationParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param accumulation
|
||||
* the accumulation to set
|
||||
*/
|
||||
public void setAccumulationParam(String accumulation) {
|
||||
this.accumulationParam = accumulation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minuend
|
||||
*/
|
||||
public String getMinuendParam() {
|
||||
return minuendParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param minuend
|
||||
* the minuend to set
|
||||
*/
|
||||
public void setMinuendParam(String minuend) {
|
||||
this.minuendParam = minuend;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the subtrahend
|
||||
*/
|
||||
public String getSubtrahendParam() {
|
||||
return subtrahendParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param subtrahend
|
||||
* the subtrahend to set
|
||||
*/
|
||||
public void setSubtrahendParam(String subtrahend) {
|
||||
this.subtrahendParam = subtrahend;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime
|
||||
* result
|
||||
+ ((accumulationParam == null) ? 0 : accumulationParam
|
||||
.hashCode());
|
||||
result = prime * result + forecastPeriodHours;
|
||||
result = prime * result
|
||||
+ ((minuendParam == null) ? 0 : minuendParam.hashCode());
|
||||
result = prime * result
|
||||
+ ((subtrahendParam == null) ? 0 : subtrahendParam.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
AccumulationCreationConfig other = (AccumulationCreationConfig) obj;
|
||||
if (accumulationParam == null) {
|
||||
if (other.accumulationParam != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!accumulationParam.equals(other.accumulationParam)) {
|
||||
return false;
|
||||
}
|
||||
if (forecastPeriodHours != other.forecastPeriodHours) {
|
||||
return false;
|
||||
}
|
||||
if (minuendParam == null) {
|
||||
if (other.minuendParam != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!minuendParam.equals(other.minuendParam)) {
|
||||
return false;
|
||||
}
|
||||
if (subtrahendParam == null) {
|
||||
if (other.subtrahendParam != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!subtrahendParam.equals(other.subtrahendParam)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,479 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.edex.plugin.grib.decoderpostprocessors.precipitation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
|
||||
import com.raytheon.edex.plugin.grib.decoderpostprocessors.DecoderPostProcessor;
|
||||
import com.raytheon.edex.plugin.grib.decoderpostprocessors.GribPostProcessor;
|
||||
import com.raytheon.edex.plugin.grib.exception.GribException;
|
||||
import com.raytheon.uf.common.dataplugin.PluginException;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridConstants;
|
||||
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel;
|
||||
import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
||||
import com.raytheon.uf.common.parameter.Parameter;
|
||||
import com.raytheon.uf.common.parameter.lookup.ParameterLookup;
|
||||
import com.raytheon.uf.common.serialization.JAXBManager;
|
||||
import com.raytheon.uf.common.serialization.SerializationException;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.common.time.TimeRange;
|
||||
import com.raytheon.uf.edex.database.DataAccessLayerException;
|
||||
import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
||||
import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
|
||||
|
||||
/**
|
||||
* Configurable grib post processor for accumulating precipitation.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 28, 2015 3756 nabowle Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PrecipAccumPostProcessor extends DecoderPostProcessor {
|
||||
|
||||
private static final GridRecord[] EMPTY_ARR = new GridRecord[0];
|
||||
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(GribPostProcessor.class);
|
||||
|
||||
/**
|
||||
* The configured set of Accumulation Configurations. Note: This is not
|
||||
* thread safe if modified.
|
||||
*/
|
||||
private static final AccumulationConfigs configs = initConfigs();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @throws JAXBException
|
||||
*/
|
||||
public PrecipAccumPostProcessor() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
if (configs == null) {
|
||||
return EMPTY_ARR;
|
||||
}
|
||||
|
||||
return generatePrecipGrids(record);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates precipitation grids for a record. If no records can be
|
||||
* generated, an empty array is returned.
|
||||
*
|
||||
* @param record
|
||||
* The record.
|
||||
* @return The generated precipitation grids, if any.
|
||||
* @throws GribException
|
||||
*/
|
||||
private GridRecord[] generatePrecipGrids(GridRecord record)
|
||||
throws GribException {
|
||||
List<GridRecord> retRecords = new ArrayList<>();
|
||||
|
||||
List<AccumulationConfig> accumConfigs = configs.getAccumulations(record
|
||||
.getDatasetId());
|
||||
|
||||
for (AccumulationConfig accumConfig : accumConfigs) {
|
||||
retRecords.addAll(generatePrecipGrids(record, accumConfig));
|
||||
}
|
||||
|
||||
return retRecords.toArray(EMPTY_ARR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates precipitation grids for a record and an accumulation config. An
|
||||
* empty collection is returned if no grids were created.
|
||||
*
|
||||
* @param record
|
||||
* The record.
|
||||
* @param accumConfig
|
||||
* An accumulation config who's model matches the record's
|
||||
* dataset id.
|
||||
* @return The created records, if any.
|
||||
* @throws GribException
|
||||
*/
|
||||
private Collection<GridRecord> generatePrecipGrids(GridRecord record,
|
||||
AccumulationConfig accumConfig) throws GribException {
|
||||
List<GridRecord> retRecords = new ArrayList<>();
|
||||
|
||||
List<AccumulationCreationConfig> creations = accumConfig.getCreations(
|
||||
record.getParameter().getAbbreviation(), true);
|
||||
for (AccumulationCreationConfig creation : creations) {
|
||||
retRecords.addAll(generatePrecipGrids(record, creation, true));
|
||||
}
|
||||
|
||||
// look for out-of-order creations where this is the subtrahend
|
||||
creations = accumConfig.getCreations(record.getParameter()
|
||||
.getAbbreviation(), false);
|
||||
for (AccumulationCreationConfig creation : creations) {
|
||||
retRecords.addAll(generatePrecipGrids(record, creation, false));
|
||||
}
|
||||
|
||||
return retRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates precipitation grids for a record and accumulation creation
|
||||
* config. An empty collection is returned if no grids were created.
|
||||
*
|
||||
* @param record
|
||||
* The record.
|
||||
* @param creation
|
||||
* The accumulation creation config.
|
||||
* @param isMinuend
|
||||
* If true, the record will is used as the minuend. If false, the
|
||||
* record is used as the subtrahend.
|
||||
* @return The created records, if any.
|
||||
* @throws GribException
|
||||
*/
|
||||
private Collection<? extends GridRecord> generatePrecipGrids(
|
||||
GridRecord record, AccumulationCreationConfig creation,
|
||||
boolean isMinuend) throws GribException {
|
||||
|
||||
List<GridRecord> minuendInv = new ArrayList<>();
|
||||
List<GridRecord> subtrahendInv = new ArrayList<>();
|
||||
Set<Integer> targetForecastInv = new HashSet<>();
|
||||
initInventories(record, isMinuend, creation, minuendInv, subtrahendInv,
|
||||
targetForecastInv);
|
||||
|
||||
List<GridRecord> retRecords = new ArrayList<>();
|
||||
int targetForecast = creation.getForecastPeriodSeconds();
|
||||
int minFcst;
|
||||
for (GridRecord minRec : minuendInv) {
|
||||
minFcst = minRec.getDataTime().getFcstTime();
|
||||
if (!targetForecastInv.contains(minFcst)) {
|
||||
targetForecastInv.add(minFcst);
|
||||
if (isMinuend && minFcst == targetForecast) {
|
||||
/*
|
||||
* this record matches the target forecast period. create a
|
||||
* copy of it with the desired parameter.
|
||||
*/
|
||||
retRecords.add(createRecord(creation, minRec, null));
|
||||
} else {
|
||||
for (GridRecord subRec : subtrahendInv) {
|
||||
if (minFcst - subRec.getDataTime().getFcstTime() == targetForecast) {
|
||||
retRecords.add(createRecord(creation, minRec,
|
||||
subRec));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes minuendInv, subtrahendInv, and targetForecastInv.
|
||||
*
|
||||
* @throws GribException
|
||||
*/
|
||||
private void initInventories(GridRecord record, boolean isMinuend,
|
||||
AccumulationCreationConfig create, List<GridRecord> minuendInv,
|
||||
List<GridRecord> subtrahendInv, Set<Integer> targetForecastInv)
|
||||
throws GribException {
|
||||
String datasetId = record.getDatasetId();
|
||||
Date refTime = record.getDataTime().getRefTime();
|
||||
if (isMinuend) {
|
||||
minuendInv.add(record);
|
||||
subtrahendInv.addAll(getPrecipInventory(refTime,
|
||||
create.getSubtrahendParam(), datasetId));
|
||||
} else {
|
||||
minuendInv.addAll(getPrecipInventory(refTime,
|
||||
create.getMinuendParam(), datasetId));
|
||||
subtrahendInv.add(record);
|
||||
}
|
||||
targetForecastInv.addAll(getPrecipForecastTimes(refTime,
|
||||
create.getAccumulationParam(), datasetId));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param creation
|
||||
* The accumulation creation config.
|
||||
* @param minRec
|
||||
* The minuend record.
|
||||
* @param subRec
|
||||
* The subtrahend record. Can be null if the minRec's forecast
|
||||
* time matches the desired forecast period, skipping the need
|
||||
* to calculate the precipitation values.
|
||||
* @return
|
||||
* @throws GribException
|
||||
*/
|
||||
protected GridRecord createRecord(AccumulationCreationConfig creation,
|
||||
GridRecord minRec, GridRecord subRec) throws GribException {
|
||||
GridRecord created = createAccumRecord(creation, minRec);
|
||||
if (subRec != null) {
|
||||
calculatePrecipValues(subRec, created);
|
||||
}
|
||||
return created;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the accumulation values. In general, this is the difference
|
||||
* between the created record's value (which is currently a copy from the
|
||||
* minuend record's value) and the subtrahend record's value, i.e.
|
||||
* createdValue[i] = minuendValue[i] - subtrahendValue[i], capped to 0 on
|
||||
* the low end.
|
||||
*
|
||||
* @param subRec
|
||||
* The subtrahend record.
|
||||
* @param created
|
||||
* The record that was created. It's expected that it's current
|
||||
* data is a copy of the minuend record's data.
|
||||
* @throws GribException
|
||||
*/
|
||||
protected void calculatePrecipValues(GridRecord subRec, GridRecord created)
|
||||
throws GribException {
|
||||
float[] subData = getMessageData(subRec);
|
||||
float[] accumData = (float[]) created.getMessageData();
|
||||
|
||||
float newVal;
|
||||
for (int i = 0; i < accumData.length; i++) {
|
||||
newVal = accumData[i] - subData[i];
|
||||
accumData[i] = newVal < 0F ? 0F : newVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the record for the accumulation based on the accumulation
|
||||
* creation config and base record.
|
||||
*
|
||||
* @param creation
|
||||
* The accumulation creation config.
|
||||
* @param baseRec
|
||||
* The record to base the accumulation off of.
|
||||
* @return
|
||||
* @throws GribException
|
||||
*/
|
||||
protected GridRecord createAccumRecord(AccumulationCreationConfig creation,
|
||||
GridRecord baseRec) throws GribException {
|
||||
|
||||
GridRecord createdRec = new GridRecord(baseRec);
|
||||
createdRec.setId(0);
|
||||
createdRec.getInfo().setId(null);
|
||||
createdRec.setDataURI(null);
|
||||
|
||||
float[] data = getMessageData(baseRec);
|
||||
float[] dataCopy = Arrays.copyOf(data, data.length);
|
||||
createdRec.setMessageData(dataCopy);
|
||||
|
||||
updateParameter(creation, baseRec, createdRec);
|
||||
updateRefTime(creation, createdRec);
|
||||
|
||||
return createdRec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the created record's datatime.
|
||||
*
|
||||
* @param creation
|
||||
* @param createdRec
|
||||
*/
|
||||
private void updateRefTime(AccumulationCreationConfig creation,
|
||||
GridRecord createdRec) {
|
||||
Calendar refTime = createdRec.getDataTime().getRefTimeAsCalendar();
|
||||
int fcstTime = createdRec.getDataTime().getFcstTime();
|
||||
|
||||
|
||||
// Calculate the end time by adding the reference time + forecast time
|
||||
Calendar endTime = (Calendar) refTime.clone();
|
||||
endTime.add(Calendar.SECOND, fcstTime);
|
||||
|
||||
// Start time is endTime - forecast period
|
||||
Calendar startTime = (Calendar) refTime.clone();
|
||||
startTime.add(Calendar.SECOND,
|
||||
fcstTime - creation.getForecastPeriodSeconds());
|
||||
|
||||
TimeRange validPeriod = new TimeRange(startTime, endTime);
|
||||
DataTime newDataTime = new DataTime(refTime, fcstTime, validPeriod);
|
||||
|
||||
createdRec.setDataTime(newDataTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the created record's parameter.
|
||||
*
|
||||
* @param creation
|
||||
* @param base
|
||||
* @param createdRec
|
||||
*/
|
||||
private void updateParameter(AccumulationCreationConfig creation,
|
||||
GridRecord base, GridRecord createdRec) {
|
||||
Parameter param = ParameterLookup.getInstance().getParameter(
|
||||
creation.getAccumulationParam());
|
||||
Parameter createdParam;
|
||||
if (param == null) {
|
||||
createdParam = new Parameter(creation.getAccumulationParam(),
|
||||
"Precipitation Accumulation", base.getParameter().getUnit());
|
||||
} else {
|
||||
createdParam = new Parameter(param.getAbbreviation(),
|
||||
param.getName(), base.getParameter().getUnit());
|
||||
}
|
||||
createdRec.setParameter(createdParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an inventory of GridRecords for the reftime, parameter
|
||||
* abbreviation, and datasetId
|
||||
*
|
||||
* @param refTime
|
||||
* The reftime.
|
||||
* @param param
|
||||
* The parameter abbreviation.
|
||||
* @param datasetId
|
||||
* The datasetId.
|
||||
* @return
|
||||
* @throws GribException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<GridRecord> getPrecipInventory(Date refTime, String param,
|
||||
String datasetId) throws GribException {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating grib dao.", e);
|
||||
}
|
||||
DatabaseQuery query = new DatabaseQuery(GridRecord.class);
|
||||
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, param);
|
||||
query.addQueryParam(GridConstants.DATASET_ID, datasetId);
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addOrder("dataTime.fcstTime", true);
|
||||
|
||||
try {
|
||||
return (List<GridRecord>) dao.queryByCriteria(query);
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException("Error getting " + param
|
||||
+ " inventory for " + datasetId, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an inventory of forecast times for the refTime, parameter
|
||||
* abbreviation, and datasetId.
|
||||
*
|
||||
* @param refTime
|
||||
* The reftime.
|
||||
* @param param
|
||||
* The parameter abbreviation.
|
||||
* @param datasetId
|
||||
* The datasetId.
|
||||
* @return
|
||||
* @throws GribException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<Integer> getPrecipForecastTimes(Date refTime, String param,
|
||||
String datasetId) throws GribException {
|
||||
GridDao dao = null;
|
||||
try {
|
||||
dao = new GridDao();
|
||||
} catch (PluginException e) {
|
||||
throw new GribException("Error instantiating grib dao!", e);
|
||||
}
|
||||
DatabaseQuery query = new DatabaseQuery(GridRecord.class);
|
||||
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, param);
|
||||
query.addQueryParam(GridConstants.DATASET_ID, datasetId);
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addReturnedField("dataTime.fcstTime");
|
||||
try {
|
||||
return (List<Integer>) dao.queryByCriteria(query);
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException("Error getting " + param
|
||||
+ " forecast inventory for " + datasetId, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the configuration.
|
||||
*/
|
||||
private static AccumulationConfigs initConfigs() {
|
||||
AccumulationConfigs retConfigs = null;
|
||||
|
||||
IPathManager pathMgr = PathManagerFactory.getPathManager();
|
||||
LocalizationLevel[] levels = new LocalizationLevel[] {
|
||||
LocalizationLevel.BASE, LocalizationLevel.REGION,
|
||||
LocalizationLevel.CONFIGURED, LocalizationLevel.SITE };
|
||||
|
||||
LocalizationFile locFile;
|
||||
|
||||
Map<LocalizationLevel, LocalizationFile> files = pathMgr
|
||||
.getTieredLocalizationFile(LocalizationType.EDEX_STATIC,
|
||||
"/grib/postProcessModels/precipitationAccumulation.xml");
|
||||
AccumulationConfigs configs = null;
|
||||
for (LocalizationLevel level : levels) {
|
||||
locFile = files.get(level);
|
||||
if (locFile == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try (InputStream is = locFile.openInputStream()) {
|
||||
JAXBManager manager = new JAXBManager(AccumulationConfigs.class);
|
||||
configs = (AccumulationConfigs) manager
|
||||
.unmarshalFromInputStream(is);
|
||||
} catch (IOException | LocalizationException | JAXBException
|
||||
| SerializationException e) {
|
||||
statusHandler
|
||||
.fatal("Could not initialize the precipitation accumulation config.",
|
||||
e);
|
||||
}
|
||||
if (retConfigs == null) {
|
||||
retConfigs = configs;
|
||||
} else {
|
||||
retConfigs.merge(configs);
|
||||
}
|
||||
}
|
||||
return retConfigs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PostProcessorType getType() {
|
||||
return PostProcessorType.POST_PERSIST;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<pluginNotificationList>
|
||||
<pluginNotification>
|
||||
<endpointName>Grid.PostProcess</endpointName>
|
||||
<format>DATAURI</format>
|
||||
<endpointType>QUEUE</endpointType>
|
||||
<durable>true</durable>
|
||||
<timeToLive>120000</timeToLive>
|
||||
<metadataMap>
|
||||
<mapping key="pluginName">
|
||||
<constraint constraintValue="grid" constraintType="EQUALS"/>
|
||||
</mapping>
|
||||
</metadataMap>
|
||||
</pluginNotification>
|
||||
</pluginNotificationList>
|
|
@ -1,129 +1,131 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<postProcessedModels>
|
||||
|
||||
<!-- Post Processor definitions for models containing grids needing to be
|
||||
stitched together -->
|
||||
<postProcessedModel>
|
||||
<modelName>UKMET[0-9]{2}|ECMF[0-9]|ENSEMBLE[0-9]{2}|AVN[0-9]{2}
|
||||
</modelName>
|
||||
<processorName>EnsembleGridAssembler</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post Processor definitions for models containing grids needing to be
|
||||
stitched together -->
|
||||
<postProcessedModel>
|
||||
<modelName>UKMET[0-9]{2}|ECMF[0-9]|ENSEMBLE[0-9]{2}|AVN[0-9]{2}
|
||||
</modelName>
|
||||
<processorName>EnsembleGridAssembler</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definitions for models which disseminate updated grids
|
||||
containing identical metadata. This data is primarily from RFCs. The overwrite
|
||||
post processor is used to prevent updated data from being discarded as duplicates. -->
|
||||
<postProcessedModel>
|
||||
<modelName>HPCqpfNDFD</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definitions for models which disseminate updated grids
|
||||
containing identical metadata. This data is primarily from RFCs. The overwrite
|
||||
post processor is used to prevent updated data from being discarded as duplicates. -->
|
||||
<postProcessedModel>
|
||||
<modelName>HPCqpfNDFD</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<postProcessedModel>
|
||||
<modelName>RFCqpf</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<postProcessedModel>
|
||||
<modelName>RFCqpf</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<postProcessedModel>
|
||||
<modelName>HPCqpf</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<postProcessedModel>
|
||||
<modelName>HPCqpf</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<postProcessedModel>
|
||||
<modelName>MPE-.*|QPE-.*</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<postProcessedModel>
|
||||
<modelName>MPE-.*|QPE-.*</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<postProcessedModel>
|
||||
<modelName>URMA25</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<postProcessedModel>
|
||||
<modelName>URMA25</modelName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for FFG grids. Similar to the models using
|
||||
the overwrite post processor, FFG gridded data is also updated without changing
|
||||
the associated metadata. In this case, the previous updates need to be retained. -->
|
||||
<postProcessedModel>
|
||||
<modelName>FFG-[A-Z]{3}</modelName>
|
||||
<processorName>FFGGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definition for FFG grids. Similar to the models using
|
||||
the overwrite post processor, FFG gridded data is also updated without changing
|
||||
the associated metadata. In this case, the previous updates need to be retained. -->
|
||||
<postProcessedModel>
|
||||
<modelName>FFG-[A-Z]{3}</modelName>
|
||||
<processorName>FFGGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definitions for models using the temperature correction
|
||||
post processor. These models may have some parameters which are incorrectly
|
||||
labeled Celsius vs. Kelvin. The list of parameters to correct is in temperatureCorrectionParameters.xml -->
|
||||
<postProcessedModel>
|
||||
<modelName>ETA218|GFS212|GFS213|ETA242|RTOFS-.*</modelName>
|
||||
<processorName>TemperatureCorrectionPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definitions for models using the temperature correction
|
||||
post processor. These models may have some parameters which are incorrectly
|
||||
labeled Celsius vs. Kelvin. The list of parameters to correct is in temperatureCorrectionParameters.xml -->
|
||||
<postProcessedModel>
|
||||
<modelName>ETA218|GFS212|GFS213|ETA242|RTOFS-.*</modelName>
|
||||
<processorName>TemperatureCorrectionPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the RTMA model -->
|
||||
<postProcessedModel>
|
||||
<modelName>RTMA</modelName>
|
||||
<processorName>RTMAGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definition for the RTMA model -->
|
||||
<postProcessedModel>
|
||||
<modelName>RTMA</modelName>
|
||||
<processorName>RTMAGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the ECMWF-HiRes model -->
|
||||
<postProcessedModel>
|
||||
<modelName>ECMWF-HiRes</modelName>
|
||||
<processorName>ECMWFHiResProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definition for the ECMWF-HiRes model -->
|
||||
<postProcessedModel>
|
||||
<modelName>ECMWF-HiRes</modelName>
|
||||
<processorName>ECMWFHiResProcessor</processorName>
|
||||
<processorName>PrecipAccumPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the MSAS model -->
|
||||
<postProcessedModel>
|
||||
<modelName>MSAS</modelName>
|
||||
<processorName>MSASPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definition for the MSAS model -->
|
||||
<postProcessedModel>
|
||||
<modelName>MSAS</modelName>
|
||||
<processorName>MSASPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the ETA (NAM80) model -->
|
||||
<postProcessedModel>
|
||||
<modelName>ETA</modelName>
|
||||
<processorName>Nam80PostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definition for the ETA (NAM80) model -->
|
||||
<postProcessedModel>
|
||||
<modelName>ETA</modelName>
|
||||
<processorName>PrecipAccumPostProcessor</processorName>
|
||||
<processorName>OverwriteGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the RUC236 model -->
|
||||
<postProcessedModel>
|
||||
<modelName>RUC236</modelName>
|
||||
<processorName>RUC236GribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definition for the RUC236 model -->
|
||||
<postProcessedModel>
|
||||
<modelName>RUC236</modelName>
|
||||
<processorName>RUC236GribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the CPCoutlook211 model -->
|
||||
<postProcessedModel>
|
||||
<modelName>CPCoutlook211</modelName>
|
||||
<processorName>CPCoutlookGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definition for the CPCoutlook211 model -->
|
||||
<postProcessedModel>
|
||||
<modelName>CPCoutlook211</modelName>
|
||||
<processorName>CPCoutlookGribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definitions for the Canadian models -->
|
||||
<postProcessedModel>
|
||||
<modelName>Canadian-NH</modelName>
|
||||
<processorName>CanadianNHPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definitions for the Canadian models -->
|
||||
<postProcessedModel>
|
||||
<modelName>Canadian-NH</modelName>
|
||||
<processorName>PrecipAccumPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<postProcessedModel>
|
||||
<modelName>Canadian-Reg</modelName>
|
||||
<processorName>CanadianRegPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<postProcessedModel>
|
||||
<modelName>Canadian-Reg</modelName>
|
||||
<processorName>PrecipAccumPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the LAPS model -->
|
||||
<postProcessedModel>
|
||||
<modelName>LAPS</modelName>
|
||||
<processorName>LapsPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post processor definition for the LAPS model -->
|
||||
<postProcessedModel>
|
||||
<modelName>LAPS</modelName>
|
||||
<processorName>LapsPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the RUC130 model -->
|
||||
<postProcessedModel>
|
||||
<modelName>RUC130</modelName>
|
||||
<processorName>RUC130GribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for HPCqpfNDFD -->
|
||||
<postProcessedModel>
|
||||
<modelName>HPCqpfNDFD</modelName>
|
||||
<!-- Post processor definition for the RUC130 model -->
|
||||
<postProcessedModel>
|
||||
<modelName>RUC130</modelName>
|
||||
<processorName>RUC130GribPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for HPCqpfNDFD -->
|
||||
<postProcessedModel>
|
||||
<modelName>HPCqpfNDFD</modelName>
|
||||
<processorName>HPCqpfPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the GFS20 model -->
|
||||
<postProcessedModel>
|
||||
<modelName>GFS215|GFS217|GFS20-*</modelName>
|
||||
<processorName>gov.noaa.nws.crh.edex.grib.decoderpostprocessor.GFS20PostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
|
||||
<!-- Post processor definition for the GFS20 model -->
|
||||
<postProcessedModel>
|
||||
<modelName>GFS215|GFS217|GFS20-.*</modelName>
|
||||
<processorName>PrecipAccumPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
<!-- Post processor definition for the HWRF model -->
|
||||
<!-- This breaks GFE and volume browser. The post processing
|
||||
creates models based on a storm's moving grid. Currently
|
||||
|
@ -137,11 +139,11 @@
|
|||
</postProcessedModel>
|
||||
-->
|
||||
|
||||
<!-- Post Processor for ARI grids (FFG source for FFMP) -->
|
||||
<postProcessedModel>
|
||||
<modelName>ARI</modelName>
|
||||
<processorName>ARIPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
<!-- Post Processor for ARI grids (FFG source for FFMP) -->
|
||||
<postProcessedModel>
|
||||
<modelName>ARI</modelName>
|
||||
<processorName>ARIPostProcessor</processorName>
|
||||
</postProcessedModel>
|
||||
|
||||
</postProcessedModels>
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<accumulationConfigs>
|
||||
<accumulation>
|
||||
<model>Canadian-Reg</model>
|
||||
<create forecastPeriodHours="3" accumulationParam="TP3hr" minuendParam="TPrun" subtrahendParam="TPrun" />
|
||||
</accumulation>
|
||||
|
||||
<accumulation>
|
||||
<model>Canadian-NH</model>
|
||||
<create forecastPeriodHours="6" accumulationParam="TP6hr" minuendParam="TPrun" subtrahendParam="TPrun" />
|
||||
</accumulation>
|
||||
|
||||
<accumulation>
|
||||
<model>ECMWF-HiRes</model>
|
||||
<create forecastPeriodHours="6" accumulationParam="TP6hr" minuendParam="TP-ECMWF" subtrahendParam="TP-ECMWF" />
|
||||
</accumulation>
|
||||
|
||||
<accumulation>
|
||||
<model>GFS215|GFS217|GFS20-.*</model>
|
||||
<create forecastPeriodHours="3" accumulationParam="TP3hr" minuendParam="TP6hr" subtrahendParam="TP3hr" />
|
||||
</accumulation>
|
||||
|
||||
<accumulation>
|
||||
<model>ETA</model>
|
||||
<create forecastPeriodHours="6" accumulationParam="TP6hr" minuendParam="TP12hr" subtrahendParam="TP6hr" />
|
||||
<create forecastPeriodHours="6" accumulationParam="CP6hr" minuendParam="CP12hr" subtrahendParam="CP6hr" />
|
||||
</accumulation>
|
||||
|
||||
<!-- NamNestPostProcessor equivalent. -->
|
||||
<!--
|
||||
<accumulation>
|
||||
<model></model>
|
||||
<create forecastPeriodHours="1" accumulationParam="TP1hr" minuendParam="TP3hr" subtrahendParam="TP2hr" />
|
||||
<create forecastPeriodHours="1" accumulationParam="TP1hr" minuendParam="TP2hr" subtrahendParam="TP1hr" />
|
||||
</accumulation>
|
||||
-->
|
||||
</accumulationConfigs>
|
Loading…
Add table
Reference in a new issue