Change-Id: I75e7a4442b305f73758500da41e2c1943fd7eba1 Former-commit-id:775fdd9a57
[formerly01859a86ed
] [formerly775fdd9a57
[formerly01859a86ed
] [formerly689af6042d
[formerly 35b0c0c81b3aeb99330a54a263c0dcfafc14bf6b]]] Former-commit-id:689af6042d
Former-commit-id:cf7bca2541
[formerly732508f606
] Former-commit-id:a0ef5636dd
This commit is contained in:
parent
fc74bce6b8
commit
89221c8701
6 changed files with 446 additions and 0 deletions
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
crh/gov.noaa.nws.crh.edex.grib.decoderpostprocessor/.project
Normal file
28
crh/gov.noaa.nws.crh.edex.grib.decoderpostprocessor/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>gov.noaa.nws.crh.edex.grib.decoderpostprocessor</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,15 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Gribpostprocessor
|
||||
Bundle-SymbolicName: gov.noaa.nws.crh.edex.grib.decoderpostprocessor
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: CRH
|
||||
Require-Bundle: com.raytheon.edex.common,
|
||||
com.raytheon.edex.plugin.grib,
|
||||
com.raytheon.uf.common.dataplugin,
|
||||
com.raytheon.uf.common.dataplugin.grid,
|
||||
com.raytheon.uf.common.parameter,
|
||||
com.raytheon.uf.edex.plugin.grid,
|
||||
com.raytheon.uf.common.datastorage,
|
||||
javax.measure
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
|
@ -0,0 +1,4 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -0,0 +1,208 @@
|
|||
package gov.noaa.nws.crh.edex.grib.decoderpostprocessor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
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.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 1-hr precipitation grids from
|
||||
* the cycling (1-hr, 2-hr, 3-hr, 1-hr, 2-hr, 3-hr, etc.) precip grids in the
|
||||
* NAM Nest output.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ----------- --------------------------
|
||||
* Sep 05, 2014 M. Foster Initial Creation
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author matthew.foster
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class NamNestPostProcessor extends OneHrPrecipGridProcessor {
|
||||
|
||||
@Override
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
// Post process the data if this is a Total Precipitation grid
|
||||
if (record.getParameter().getAbbreviation().equals("TP2hr") ||
|
||||
record.getParameter().getAbbreviation().equals("TP3hr")) {
|
||||
return super.process(record);
|
||||
}
|
||||
return new GridRecord[] { record };
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a grid inventory for the provided datasetid and parameter
|
||||
*
|
||||
* @param datasetid
|
||||
* The datasetid of the model being worked on
|
||||
* @param parm
|
||||
* The parameter being retrieved (e.g. TP3hr)
|
||||
* @param refTime
|
||||
* The refTime (cycle time) of the model
|
||||
* @return A List of GridRecord
|
||||
* @throws GribException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<GridRecord> getPrecipInventory(String datasetid,
|
||||
String parm, 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, parm);
|
||||
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(
|
||||
String.format("Error getting Precip inventory for %s!",
|
||||
datasetid), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param refTime
|
||||
* The reftime (cycle time) of the model being worked on
|
||||
* @return List of Integer of the fcstTimes of the current 1hr precip
|
||||
* inventory
|
||||
* @throws GribException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected HashSet<Integer> getPrecip1hrInventory(String datasetId, 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, "TP1hr");
|
||||
query.addQueryParam(GridConstants.DATASET_ID, datasetId,
|
||||
QueryOperand.EQUALS);
|
||||
query.addQueryParam("dataTime.refTime", refTime);
|
||||
query.addReturnedField("dataTime.fcstTime");
|
||||
query.setDistinct(true);
|
||||
try {
|
||||
return new HashSet<Integer>((List<Integer>) dao.queryByCriteria(query));
|
||||
} catch (DataAccessLayerException e) {
|
||||
throw new GribException(
|
||||
"Error getting Precip inventory for NAMNest!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the 1 hour accumulated grid from the run accumulated
|
||||
* precipitation grids. This function will look in the inventory and
|
||||
* generate any 1 hr grids that can be generated.
|
||||
*
|
||||
* @param record
|
||||
* The grib record for which to generate the 1 hour accumulated
|
||||
* precipitation grid
|
||||
* @return The generated 1-hr precipitation grids
|
||||
* @throws GribException
|
||||
*/
|
||||
protected synchronized GridRecord[] generate1hrPrecipGrids(GridRecord record)
|
||||
throws GribException {
|
||||
|
||||
List<GridRecord> currInventory;
|
||||
List<GridRecord> prevInventory;
|
||||
HashSet<Integer> precip1hrInventory;
|
||||
|
||||
if (record.getParameter().getAbbreviation().equals("TP3hr")) {
|
||||
// Get an inventory of TP3hr grids
|
||||
currInventory = getPrecipInventory(record.getDatasetId(), "TP3hr",
|
||||
record.getDataTime().getRefTime());
|
||||
|
||||
// Get an inventory of TP2hr grids
|
||||
prevInventory = getPrecipInventory(record.getDatasetId(), "TP2hr",
|
||||
record.getDataTime().getRefTime());
|
||||
|
||||
// The current 1hr precip inventory
|
||||
precip1hrInventory = getPrecip1hrInventory(record.getDatasetId(),
|
||||
record.getDataTime().getRefTime());
|
||||
|
||||
} else if (record.getParameter().getAbbreviation().equals("TP2hr")) {
|
||||
// Get an inventory of TP2hr grids
|
||||
currInventory = getPrecipInventory(record.getDatasetId(), "TP2hr",
|
||||
record.getDataTime().getRefTime());
|
||||
// Get an inventory of TP1hr grids
|
||||
prevInventory = getPrecipInventory(record.getDatasetId(), "TP1hr",
|
||||
record.getDataTime().getRefTime());
|
||||
|
||||
precip1hrInventory = new HashSet<Integer>();
|
||||
for (GridRecord rec : prevInventory) {
|
||||
precip1hrInventory.add(rec.getDataTime().getFcstTime());
|
||||
}
|
||||
} else {
|
||||
throw new GribException("Didn't get TP3hr or TP2hr grid");
|
||||
}
|
||||
|
||||
// Adds the current record to the precip inventory
|
||||
float[] currentData = (float[]) record.getMessageData();
|
||||
record.setMessageData(currentData);
|
||||
currInventory.add(record);
|
||||
|
||||
// Examine each grid in the inventory and generate the 1hr precipitation
|
||||
// grid if possible
|
||||
List<GridRecord> generatedRecords = new ArrayList<GridRecord>();
|
||||
for (GridRecord currRecord : currInventory) {
|
||||
// Check if the 1hr precipitation grid has already been produced
|
||||
if (! precip1hrInventory.contains(currRecord.getDataTime()
|
||||
.getFcstTime())) {
|
||||
List<GridRecord> generated1hrPrecips = generate1hrPrecip(
|
||||
currRecord, prevInventory);
|
||||
for (GridRecord newRecord : generated1hrPrecips) {
|
||||
// Add the generated grid to the current inventory
|
||||
if (newRecord != null) {
|
||||
precip1hrInventory.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,184 @@
|
|||
package gov.noaa.nws.crh.edex.grib.decoderpostprocessor;
|
||||
|
||||
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.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 1-hour precip grids
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- ------------- --------------------------
|
||||
* Sep 05, 2014 M. Foster Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author matthew.foster
|
||||
* @version 1.0
|
||||
*
|
||||
*/
|
||||
|
||||
public abstract class OneHrPrecipGridProcessor implements IDecoderPostProcessor {
|
||||
/** The number of seconds in 1 hour */
|
||||
protected static final int SECONDS_IN_1_HR = 3600;
|
||||
|
||||
public GridRecord[] process(GridRecord record) throws GribException {
|
||||
|
||||
// Post process the data if this is a 2hr or 3hr precip accumulation
|
||||
|
||||
GridRecord[] newRecords = generate1hrPrecipGrids(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[] generate1hrPrecipGrids(GridRecord record)
|
||||
throws GribException;
|
||||
|
||||
/**
|
||||
* Generates the 1hr precipitation grid
|
||||
*
|
||||
* @param record
|
||||
* The current record to clone and modify to produce the new 1hr
|
||||
* grid
|
||||
* @param precipInventory
|
||||
* The current run accumulated grid inventory
|
||||
* @return The generated 1hr precipitation grid
|
||||
* @throws GribException
|
||||
*/
|
||||
protected List<GridRecord> generate1hrPrecip(GridRecord record,
|
||||
List<GridRecord> precipInventory)
|
||||
throws GribException {
|
||||
List<GridRecord> tp1hrRecords = new ArrayList<GridRecord>();
|
||||
int currentFcstTime = record.getDataTime().getFcstTime();
|
||||
|
||||
for (GridRecord rec : precipInventory) {
|
||||
if (rec.getDataTime().getFcstTime() == (currentFcstTime - SECONDS_IN_1_HR)) {
|
||||
tp1hrRecords.add(calculate1hrPrecip(rec, record));
|
||||
}
|
||||
}
|
||||
return tp1hrRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the 1hr 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 1hr precipitation grid
|
||||
* @throws GribException
|
||||
*/
|
||||
protected GridRecord calculate1hrPrecip(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 tp1hrRecord = new GridRecord(currentRecord);
|
||||
tp1hrRecord.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);
|
||||
tp1hrRecord.setMessageData(newData);
|
||||
|
||||
// Assign the new parameter abbreviation and cache it if necessary
|
||||
|
||||
Parameter param = new Parameter("TP1hr", "Precip Accum 1 hr",
|
||||
currentRecord.getParameter().getUnit());
|
||||
tp1hrRecord.setParameter(param);
|
||||
tp1hrRecord.getInfo().setId(null);
|
||||
// Change the data time to include the 1-hr time range
|
||||
modifyDataTime(tp1hrRecord);
|
||||
|
||||
// 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[]) tp1hrRecord.getMessageData());
|
||||
}
|
||||
return tp1hrRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 1hr 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 1 hour from the reference
|
||||
// time + forecast time
|
||||
Calendar startTime = (Calendar) refTime.clone();
|
||||
startTime.add(Calendar.SECOND, fcstTime - SECONDS_IN_1_HR);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue