Merge "Issue #1787 Fixed to support changes to D2D grid location" into omaha_13.4.1

Former-commit-id: 5a11d3cc1c [formerly 73e3a04a98ced3670c61b5debacdfc79d494ab29]
Former-commit-id: 390bf03c39
This commit is contained in:
Richard Peter 2013-04-16 09:35:12 -05:00 committed by Gerrit Code Review
commit 30e77171ab
7 changed files with 237 additions and 302 deletions

View file

@ -2,6 +2,6 @@
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.5</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
</pydev_project>

View file

@ -32,8 +32,9 @@ import JUtil
# ------------ ---------- ----------- --------------------------
# 04/10/08 chammack Initial Creation.
# 09/30/08 1566 wdougher Quit returning TimeRange from overlaps(), etc.
# 09/16/09 2899 njensen Huge performance boost by caching
#
# 09/16/09 2899 njensen Huge performance boost by caching
# 04/04/2013 #1787 randerso Removed isValid check to allow 0 duration
# time ranges to be used in python
#
#
@ -159,8 +160,6 @@ def javaTimeRangeListToPyList(timeRanges):
return pylist
def encodeJavaTimeRange(javaTimeRange):
if not javaTimeRange.isValid():
return None
time = TimeRange(javaTimeRange)
start = time.startTime()
end = time.endTime()

View file

@ -24,7 +24,10 @@
# 02/16/12 14439 jdynina modified haines thresholds
# 02/16/12 13917 jdynina merged in changes from TRAC ticket 11391
# 07/25/12 #957 dgilling implement edit areas as args to calc methods.
# 10/5/12 15158 ryu add Forecaster.getDb()
# 10/05/12 15158 ryu add Forecaster.getDb()
# 04/04/13 #1787 randerso fix validTime check to work with accumulative parms
# fix logging so you can actually determine why
# a smartInit is not calculating a parameter
#
##
import string, sys, re, time, types, getopt, fnmatch, LogStream, DatabaseID, JUtil, AbsTime, TimeRange
@ -836,8 +839,8 @@ class Forecaster(GridUtilities):
def __sortTimes(self, methods, validTime):
rval = []
calced = []
haveNoData = {}
for we, mthd, args in methods:
# LogStream.logEvent("Evaluating times for calc"+we)
calced.append(we)
args = filter(lambda x, ma=self.magicArgs().keys() + [we]:
x not in ma, args)
@ -865,27 +868,36 @@ class Forecaster(GridUtilities):
if validTime is None:
valid = True
elif jtr.contains(validTime):
valid = True
else:
# need check to be inclusive on both ends for methods that
# need both accumulative and non-accumulative parms
valid = validTime.getTime() >= jtr.getStart().getTime() and \
validTime.getTime() <= jtr.getEnd().getTime()
if valid:
timelist = TimeRange.encodeJavaTimeRange(jtr)
pylist.append(timelist)
ttimes.append(pylist)
timeList = ttimes[len(ttimes)-1]
result = 0
for xtime in timeList:
result += xtime[1] - xtime[0]
if result == 0:
if not haveNoData.has_key(we):
haveNoData[we] = [p]
else:
haveNoData[we].append(p)
# msg = "Times available for " + p + " " + str(validTime) + ":\n"
# timeList = ttimes[len(ttimes)-1]
# for xtime in timeList:
# msg += '('
# stime = time.gmtime(xtime[0])
# etime = time.gmtime(xtime[1])
# stime = time.strftime('%Y%m%d_%H%M', stime)
# etime = time.strftime('%Y%m%d_%H%M', etime)
# msg += stime + ", " + etime
# msg += ')\n'
# LogStream.logEvent(msg)
# compare the times of each parm and find where they match up
times = self.__compTimes(None, ttimes)
# LogStream.logEvent("nargs:",nargs)
# LogStream.logEvent("ttimes:",ttimes)
# LogStream.logEvent("times:",times)
hadDataButSkipped = {}
for i in range(len(ttimes)):
timeList = ttimes[i]
@ -896,7 +908,16 @@ class Forecaster(GridUtilities):
hadDataButSkipped[xtime].append(parmName)
else:
hadDataButSkipped[xtime] = [parmName]
# LogStream.logEvent("hadDataButSkipped:",hadDataButSkipped)
hadNoData = []
for i in range(len(nargs)):
timeList = ttimes[i]
parmName = nargs[i]
if len(timeList) == 0:
hadNoData.append(parmName)
# LogStream.logEvent("hadNoData:",hadNoData)
missing = {}
for xtime in hadDataButSkipped:
stime = time.gmtime(xtime[0])
@ -908,16 +929,17 @@ class Forecaster(GridUtilities):
for parmName in nargs:
if not hadDataButSkipped[xtime].__contains__(parmName):
if parmName in calced:
if haveNoData.has_key(parmName):
missing[msg].append(parmName)
else:
if parmName in haveNoData.values():
missing[msg].append(parmName)
if not len(missing[msg]):
del missing[msg]
missing[msg].append(parmName)
if len(missing) == 0 and len(hadNoData) > 0:
msg = ''
if (validTime is not None):
vtime = validTime.getTime()/1000
vtime = time.gmtime(vtime)
msg = time.strftime('%Y%m%d_%H%M', vtime)
missing[msg] = hadNoData
# LogStream.logEvent("missing:",missing)
if len(missing):
LogStream.logEvent("Skipping calc" + we + " for some times due to the following " +
"missing data:", missing)
@ -1130,7 +1152,7 @@ class Forecaster(GridUtilities):
parm = self.__getNewWE(m[0])
tr = parm.getTimeRange(t[0])
# A vaild time range was not found so the parameter
# A valid time range was not found so the parameter
# cannot be calculated, so continue
if not tr.isValid():
continue

View file

@ -22,35 +22,20 @@ package com.raytheon.edex.plugin.gfe.db.dao;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import com.raytheon.edex.plugin.gfe.config.IFPServerConfig;
import com.raytheon.edex.plugin.gfe.config.IFPServerConfigManager;
import com.raytheon.edex.plugin.gfe.exception.GfeConfigurationException;
import com.raytheon.edex.plugin.gfe.util.GridTranslator;
import com.raytheon.uf.common.comm.CommunicationException;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.DatabaseID;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.GridParmInfo;
import com.raytheon.uf.common.dataplugin.gfe.db.objects.ParmID;
import com.raytheon.uf.common.dataplugin.grid.GridConstants;
import com.raytheon.uf.common.dataplugin.grid.GridInfoConstants;
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
import com.raytheon.uf.common.dataplugin.level.Level;
import com.raytheon.uf.common.dataplugin.level.LevelFactory;
import com.raytheon.uf.common.parameter.mapping.ParameterMapper;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.util.mapping.MultipleMappingException;
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;
@ -63,6 +48,9 @@ import com.raytheon.uf.edex.plugin.grid.dao.GridDao;
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* 03/20/13 #1774 randerso Refactored out of GFEDao
* 04/04/13 #1787 randerso Fixed to support changes to D2D grid location
* Additional cleanup to move the D2D to GFE translation
* logic into D2DGridDatabase.
*
* </pre>
*
@ -81,27 +69,6 @@ public class GFED2DDao extends GridDao {
private static final String REF_TIME = "dataTime.refTime";
// hibernate query to find grid info record for the given datasetId and
// parameter
private static final String SQL_D2D_GRID_PARM_QUERY = "select parameter_abbreviation, id "
+ "FROM grid_info WHERE "
+ GridInfoConstants.DATASET_ID
+ " = :"
+ GridInfoConstants.DATASET_ID
+ " AND "
+ "level_id = :level_id AND "
+ "(lower(parameter_abbreviation) = :abbrev OR lower(parameter_abbreviation) like :hourAbbrev)";
// hibernate query to find the times for the GridRecord for the given
// info.id, id returned to allow easy lookup of the record associated with
// the time
private static final String HQL_D2D_GRID_TIME_QUERY = "select dataTime.fcstTime, id from GridRecord "
+ "where "
+ GridConstants.INFO_ID
+ " = :info_id AND dataTime.refTime = :refTime order by dataTime.fcstTime";
private static final Pattern WIND_PATTERN = Pattern.compile("wind");
public GFED2DDao() throws PluginException {
super();
}
@ -116,20 +83,12 @@ public class GFED2DDao extends GridDao {
* @throws DataAccessLayerException
* If errors occur while querying the metadata database
*/
public List<Integer> getD2DForecastTimes(DatabaseID dbId)
public List<Integer> getForecastTimes(String d2dModelName, Date refTime)
throws DataAccessLayerException {
DatabaseQuery query = new DatabaseQuery(GridRecord.class.getName());
query.addDistinctParameter(FCST_TIME);
try {
IFPServerConfig config = IFPServerConfigManager
.getServerConfig(dbId.getSiteId());
query.addQueryParam(GridConstants.DATASET_ID,
config.d2dModelNameMapping(dbId.getModelName()));
} catch (GfeConfigurationException e) {
throw new DataAccessLayerException(
"Error occurred looking up model name mapping", e);
}
query.addQueryParam(REF_TIME, dbId.getModelTimeAsDate());
query.addQueryParam(GridConstants.DATASET_ID, d2dModelName);
query.addQueryParam(REF_TIME, refTime);
query.addOrder(FCST_TIME, true);
@SuppressWarnings("unchecked")
@ -152,14 +111,16 @@ public class GFED2DDao extends GridDao {
* @throws DataAccessLayerException
* If errors occur while querying the metadata database
*/
public GridRecord getD2DGrid(ParmID id, Integer forecastTime,
public GridRecord getGrid(String d2dModelName, Date refTime,
String d2dParmName, Level d2dLevel, Integer forecastTime,
GridParmInfo info) throws DataAccessLayerException {
Session s = null;
try {
s = getHibernateTemplate().getSessionFactory().openSession();
// TODO: clean up so we only make one db query
SortedMap<Integer, Integer> rawTimes = queryByD2DParmId(id, s);
SortedMap<Integer, Integer> rawTimes = queryByParmId(d2dModelName,
refTime, d2dParmName, d2dLevel, s);
// if forecastTime is null just pick one,
// this is for static data since all times are the same
@ -198,108 +159,75 @@ public class GFED2DDao extends GridDao {
* @throws DataAccessLayerException
* If errors occur while querying the metadata database
*/
public SortedMap<Integer, Integer> queryByD2DParmId(ParmID id, Session s)
public SortedMap<Integer, Integer> queryByParmId(String d2dModelName,
Date refTime, String d2dParmName, Level d2dLevel, Session s)
throws DataAccessLayerException {
String levelName = GridTranslator.getLevelName(id.getParmLevel());
double[] levelValues = GridTranslator.getLevelValue(id.getParmLevel());
boolean levelOnePresent = (levelValues[0] != Level
.getInvalidLevelValue());
boolean levelTwoPresent = (levelValues[1] != Level
.getInvalidLevelValue());
Level level = null;
// to have a level 2, must have a level one
try {
if (levelOnePresent && levelTwoPresent) {
level = LevelFactory.getInstance().getLevel(levelName,
levelValues[0], levelValues[1]);
} else if (levelOnePresent) {
level = LevelFactory.getInstance().getLevel(levelName,
levelValues[0]);
} else {
level = LevelFactory.getInstance().getLevel(levelName, 0.0);
}
} catch (CommunicationException e) {
logger.error(e.getLocalizedMessage(), e);
}
if (level == null) {
logger.warn("Unable to query D2D parms, ParmID " + id
+ " does not map to a level");
return new TreeMap<Integer, Integer>();
}
SQLQuery modelQuery = s.createSQLQuery(SQL_D2D_GRID_PARM_QUERY);
modelQuery.setLong("level_id", level.getId());
DatabaseID dbId = id.getDbId();
try {
IFPServerConfig config = IFPServerConfigManager
.getServerConfig(dbId.getSiteId());
modelQuery.setString(GridInfoConstants.DATASET_ID,
config.d2dModelNameMapping(dbId.getModelName()));
} catch (GfeConfigurationException e) {
throw new DataAccessLayerException(
"Error occurred looking up model name mapping", e);
}
String abbreviation = null;
try {
abbreviation = ParameterMapper.getInstance().lookupBaseName(
id.getParmName(), "gfeParamName");
} catch (MultipleMappingException e) {
statusHandler.handle(Priority.WARN, e.getLocalizedMessage(), e);
abbreviation = e.getArbitraryMapping();
}
abbreviation = abbreviation.toLowerCase();
modelQuery.setString("abbrev", abbreviation);
modelQuery.setString("hourAbbrev", abbreviation + "%hr");
DatabaseQuery query = new DatabaseQuery(GridRecord.class.getName());
query.addReturnedField(FCST_TIME);
query.addReturnedField("id");
query.addQueryParam(GridConstants.DATASET_ID, d2dModelName);
query.addQueryParam(REF_TIME, refTime);
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION, d2dParmName);
query.addQueryParam(GridConstants.LEVEL_ID, d2dLevel.getId());
query.addOrder(FCST_TIME, true);
@SuppressWarnings("unchecked")
List<Object[]> results = modelQuery.list();
Integer modelId = null;
if (results.size() == 0) {
return new TreeMap<Integer, Integer>();
} else if (results.size() > 1) {
// hours matched, take hour with least number that matches exact
// param
Pattern p = Pattern.compile("^" + abbreviation + "(\\d+)hr$");
int lowestHr = -1;
for (Object[] rows : results) {
String param = ((String) rows[0]).toLowerCase();
if (param.equals(abbreviation) && (lowestHr < 0)) {
modelId = (Integer) rows[1];
} else {
Matcher matcher = p.matcher(param);
if (matcher.matches()) {
int hr = Integer.parseInt(matcher.group(1));
if ((lowestHr < 0) || (hr < lowestHr)) {
modelId = (Integer) rows[1];
lowestHr = hr;
}
}
}
}
} else {
modelId = (Integer) (results.get(0))[1];
}
Query timeQuery = s.createQuery(HQL_D2D_GRID_TIME_QUERY);
timeQuery.setInteger("info_id", modelId);
timeQuery.setParameter("refTime", dbId.getModelTimeAsDate());
@SuppressWarnings("unchecked")
List<Object[]> timeResults = timeQuery.list();
if (timeResults.isEmpty()) {
return new TreeMap<Integer, Integer>();
}
List<Object[]> firstTry = (List<Object[]>) this.queryByCriteria(query);
SortedMap<Integer, Integer> dataTimes = new TreeMap<Integer, Integer>();
for (Object[] rows : timeResults) {
dataTimes.put((Integer) rows[0], (Integer) rows[1]);
if (firstTry.isEmpty()) {
query = new DatabaseQuery(GridRecord.class.getName());
query.addReturnedField(FCST_TIME);
query.addReturnedField("id");
query.addReturnedField(GridConstants.PARAMETER_ABBREVIATION);
query.addQueryParam(GridConstants.DATASET_ID, d2dModelName);
query.addQueryParam(REF_TIME, refTime);
query.addQueryParam(GridConstants.PARAMETER_ABBREVIATION,
d2dParmName + "%hr", QueryOperand.LIKE);
query.addQueryParam(GridConstants.LEVEL_ID, d2dLevel.getId());
query.addOrder(FCST_TIME, true);
query.addOrder(GridConstants.PARAMETER_ABBREVIATION, true);
@SuppressWarnings("unchecked")
List<Object[]> secondTry = (List<Object[]>) this
.queryByCriteria(query);
Pattern p = Pattern.compile("^" + d2dParmName + "(\\d+)hr$");
int i = 0;
while (i < secondTry.size()) {
Object[] row = secondTry.get(i++);
Integer fcstHr = (Integer) row[0];
Integer id = (Integer) row[1];
Matcher matcher = p.matcher((String) row[2]);
int dur = Integer.MAX_VALUE;
if (matcher.matches()) {
dur = Integer.parseInt(matcher.group(1));
}
for (int j = i; j < secondTry.size(); j++) {
Object[] nextRow = secondTry.get(j);
if (fcstHr.equals(nextRow[0])) {
i = j;
String nextParam = (String) nextRow[2];
Matcher nextMatcher = p.matcher(nextParam);
int nextDur = Integer.MAX_VALUE;
if (nextMatcher.matches()) {
nextDur = Integer.parseInt(nextMatcher.group(1));
}
if (nextDur < dur) {
id = (Integer) nextRow[1];
}
} else {
break;
}
}
dataTimes.put(fcstHr, id);
}
} else {
for (Object[] row : firstTry) {
dataTimes.put((Integer) row[0], (Integer) row[1]);
}
}
return dataTimes;
}
@ -311,66 +239,18 @@ public class GFED2DDao extends GridDao {
* @return the list of forecast hours
* @throws DataAccessLayerException
*/
public List<Integer> queryFcstHourByD2DParmId(ParmID id)
public List<Integer> queryFcstHourByParmId(String d2dModelName,
Date refTime, String d2dParmName, Level d2dLevel)
throws DataAccessLayerException {
List<Integer> timeList = new ArrayList<Integer>();
Session s = null;
try {
s = getHibernateTemplate().getSessionFactory().openSession();
if (id.getParmName().equalsIgnoreCase("wind")) {
String idString = id.toString();
Matcher idWindMatcher = WIND_PATTERN.matcher(idString);
ParmID uWindId = new ParmID(idWindMatcher.replaceAll("uW"));
SortedMap<Integer, Integer> results = queryByD2DParmId(uWindId,
s);
List<Integer> uTimeList = new ArrayList<Integer>(results.size());
for (Integer o : results.keySet()) {
uTimeList.add(o);
}
ParmID vWindId = new ParmID(idWindMatcher.replaceAll("vW"));
results = queryByD2DParmId(vWindId, s);
Set<Integer> vTimeList = new HashSet<Integer>(results.size(), 1);
for (Integer o : results.keySet()) {
vTimeList.add(o);
}
for (Integer tr : uTimeList) {
if (vTimeList.contains(tr)) {
timeList.add(tr);
}
}
if (!timeList.isEmpty()) {
return timeList;
}
ParmID sWindId = new ParmID(idWindMatcher.replaceAll("ws"));
results = queryByD2DParmId(sWindId, s);
List<Integer> sTimeList = new ArrayList<Integer>(results.size());
for (Integer o : results.keySet()) {
sTimeList.add(o);
}
ParmID dWindId = new ParmID(idWindMatcher.replaceAll("wd"));
results = queryByD2DParmId(dWindId, s);
Set<Integer> dTimeList = new HashSet<Integer>(results.size(), 1);
for (Integer o : results.keySet()) {
dTimeList.add(o);
}
for (Integer tr : sTimeList) {
if (dTimeList.contains(tr)) {
timeList.add(tr);
}
}
} else {
SortedMap<Integer, Integer> results = queryByD2DParmId(id, s);
for (Integer o : results.keySet()) {
timeList.add(o);
}
SortedMap<Integer, Integer> results = queryByParmId(d2dModelName,
refTime, d2dParmName, d2dLevel, s);
for (Integer o : results.keySet()) {
timeList.add(o);
}
} finally {
if (s != null) {
@ -395,7 +275,7 @@ public class GFED2DDao extends GridDao {
* @return
* @throws DataAccessLayerException
*/
public List<Date> getD2DModelRunTimes(String d2dModelName, int maxRecords)
public List<Date> getModelRunTimes(String d2dModelName, int maxRecords)
throws DataAccessLayerException {
DatabaseQuery query = new DatabaseQuery(GridRecord.class.getName());
query.addDistinctParameter(REF_TIME);

View file

@ -23,7 +23,6 @@ package com.raytheon.edex.plugin.gfe.server.database;
import java.awt.Rectangle;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@ -46,6 +45,7 @@ import com.raytheon.edex.plugin.gfe.paraminfo.GridParamInfoLookup;
import com.raytheon.edex.plugin.gfe.paraminfo.ParameterInfo;
import com.raytheon.edex.plugin.gfe.server.GridParmManager;
import com.raytheon.edex.plugin.gfe.util.GridTranslator;
import com.raytheon.uf.common.comm.CommunicationException;
import com.raytheon.uf.common.dataplugin.PluginException;
import com.raytheon.uf.common.dataplugin.gfe.GridDataHistory;
import com.raytheon.uf.common.dataplugin.gfe.RemapGrid;
@ -65,6 +65,7 @@ import com.raytheon.uf.common.dataplugin.gfe.slice.VectorGridSlice;
import com.raytheon.uf.common.dataplugin.grid.GridPathProvider;
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
import com.raytheon.uf.common.dataplugin.level.Level;
import com.raytheon.uf.common.dataplugin.level.LevelFactory;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.Request;
@ -101,7 +102,8 @@ import com.raytheon.uf.edex.database.DataAccessLayerException;
* data instead of full grid. Added logging to support
* GFE performance testing
* 03/19/2013 #1774 randerso Fix accumulative grid time ranges
* Apr 01, 2013 #1774 randerso Moved wind component checking to GfeIngestNotificaionFilter
* 04/04/2013 #1774 randerso Moved wind component checking to GfeIngestNotificaionFilter
* 04/04/2013 #1787 randerso Move the D2D to GFE translation logic out of GFED2DDao
*
* </pre>
*
@ -167,8 +169,7 @@ public class D2DGridDatabase extends VGridDatabase {
try {
GFED2DDao dao = new GFED2DDao();
List<Date> result = dao.getD2DModelRunTimes(d2dModelName,
maxRecords);
List<Date> result = dao.getModelRunTimes(d2dModelName, maxRecords);
List<DatabaseID> dbInventory = new ArrayList<DatabaseID>();
for (Date date : result) {
@ -209,6 +210,8 @@ public class D2DGridDatabase extends VGridDatabase {
private String[] components;
private Level level;
public D2DParm(ParmID parmId, GridParmInfo gpi,
Map<Integer, TimeRange> fcstHrToTimeRange, String... components) {
this.parmId = parmId;
@ -222,6 +225,8 @@ public class D2DGridDatabase extends VGridDatabase {
for (Entry<Integer, TimeRange> entry : fcstHrToTimeRange.entrySet()) {
this.timeRangeToFcstHr.put(entry.getValue(), entry.getKey());
}
this.level = getD2DLevel(parmId.getParmLevel());
}
public ParmID getParmId() {
@ -244,6 +249,10 @@ public class D2DGridDatabase extends VGridDatabase {
return components;
}
public Level getLevel() {
return level;
}
@Override
public String toString() {
return this.parmId.toString();
@ -252,7 +261,7 @@ public class D2DGridDatabase extends VGridDatabase {
private String d2dModelName;
private Date modelTime;
private Date refTime;
private GridParamInfo modelInfo;
@ -275,20 +284,20 @@ public class D2DGridDatabase extends VGridDatabase {
* The database ID of this database
*/
public D2DGridDatabase(IFPServerConfig config, String d2dModelName,
Date modelTime) throws GfeException {
Date refTime) throws GfeException {
super(config);
this.d2dModelName = d2dModelName;
this.modelTime = modelTime;
this.refTime = refTime;
this.modelInfo = GridParamInfoLookup.getInstance().getGridParamInfo(
d2dModelName);
if (modelInfo == null) {
throw new GfeException("No model info for: " + d2dModelName);
}
this.availableTimes = modelInfo.getAvailableTimes(modelTime);
this.availableTimes = modelInfo.getAvailableTimes(refTime);
// Get the database id for this database.
this.dbId = getDbId(this.d2dModelName, this.modelTime, this.config);
this.dbId = getDbId(this.d2dModelName, this.refTime, this.config);
this.valid = this.dbId.isValid();
// get the output gloc'
@ -409,8 +418,10 @@ public class D2DGridDatabase extends VGridDatabase {
}
}
String d2dParmName = getD2DParmName(atts.getShort_name());
D2DParm d2dParm = new D2DParm(pid, gpi, possibleInventorySlots,
atts.getShort_name());
d2dParmName);
this.gfeParms.put(pid, d2dParm);
this.d2dParms.put(compositeName(atts.getShort_name(), level), d2dParm);
}
@ -450,8 +461,11 @@ public class D2DGridDatabase extends VGridDatabase {
availableTimes.get(i));
}
String uD2dParmName = getD2DParmName(uatts.getShort_name());
String vD2dParmName = getD2DParmName(vatts.getShort_name());
D2DParm d2dParm = new D2DParm(pid, gpi, possibleInventorySlots,
uatts.getShort_name(), vatts.getShort_name());
uD2dParmName, vD2dParmName);
this.gfeParms.put(pid, d2dParm);
this.d2dParms.put(compositeName(uatts.getShort_name(), level), d2dParm);
this.d2dParms.put(compositeName(vatts.getShort_name(), level), d2dParm);
@ -514,10 +528,8 @@ public class D2DGridDatabase extends VGridDatabase {
// get database inventory where all components are available
for (String component : parm.getComponents()) {
ParmID compPid = new ParmID(component, dbId,
id.getParmLevel());
List<Integer> compInv = dao
.queryFcstHourByD2DParmId(compPid);
List<Integer> compInv = dao.queryFcstHourByParmId(
d2dModelName, refTime, component, parm.getLevel());
if (dbInv == null) {
dbInv = compInv;
@ -828,17 +840,18 @@ public class D2DGridDatabase extends VGridDatabase {
try {
// Gets the metadata from the grib metadata database
D2DParm parm = this.gfeParms.get(parmId);
Integer fcstHr = null;
if (!GridPathProvider.STATIC_PARAMETERS.contains(parmId
.getParmName())) {
D2DParm parm = this.gfeParms.get(parmId);
fcstHr = parm.getTimeRangeToFcstHr().get(timeRange);
if (fcstHr == null) {
throw new GfeException("Invalid time range " + timeRange
+ " for " + parmId);
}
}
d2dRecord = dao.getD2DGrid(parmId, fcstHr, gpi);
d2dRecord = dao.getGrid(d2dModelName, refTime,
parm.getComponents()[0], parm.getLevel(), fcstHr, gpi);
} catch (DataAccessLayerException e) {
throw new GfeException(
"Error retrieving D2D Grid record from database", e);
@ -955,21 +968,18 @@ public class D2DGridDatabase extends VGridDatabase {
+ parmId);
}
String mappedModel = config.d2dModelNameMapping(dbId.getModelName());
if (windParm.getComponents()[0].equals("uw")) {
// TODO clean up the hard coded d2d parm names
if (windParm.getComponents()[0].equals("uW")) {
try {
GridRecord uRecord = null;
GridRecord vRecord = null;
// Get the metadata from the grib metadata database
uRecord = dao.getD2DGrid(
new ParmID("uw", this.dbId, parmId.getParmLevel()),
fcstHr, gpi);
vRecord = dao.getD2DGrid(
new ParmID("vw", this.dbId, parmId.getParmLevel()),
fcstHr, gpi);
uRecord = dao.getGrid(d2dModelName, refTime, "uW",
windParm.getLevel(), fcstHr, gpi);
vRecord = dao.getGrid(d2dModelName, refTime, "vW",
windParm.getLevel(), fcstHr, gpi);
// Gets the raw grid data from the D2D grib HDF5 files
Grid2DFloat uData = getRawGridData(uRecord);
@ -977,8 +987,7 @@ public class D2DGridDatabase extends VGridDatabase {
// Resample the data to fit the desired region
float fillV = Float.MAX_VALUE;
ParameterInfo pa = GridParamInfoLookup.getInstance()
.getParameterInfo(mappedModel, "uw");
ParameterInfo pa = modelInfo.getParameterInfo("uw");
if (pa != null) {
fillV = pa.getFillValue();
}
@ -1003,12 +1012,10 @@ public class D2DGridDatabase extends VGridDatabase {
GridRecord dRecord = null;
// Get the metadata from the grib metadata database
sRecord = dao.getD2DGrid(
new ParmID("ws", this.dbId, parmId.getParmLevel()),
fcstHr, gpi);
dRecord = dao.getD2DGrid(
new ParmID("wd", this.dbId, parmId.getParmLevel()),
fcstHr, gpi);
sRecord = dao.getGrid(d2dModelName, refTime, "WS",
windParm.getLevel(), fcstHr, gpi);
dRecord = dao.getGrid(d2dModelName, refTime, "WD",
windParm.getLevel(), fcstHr, gpi);
// Gets the raw grid data from the D2D grib HDF5 files
Grid2DFloat sData = getRawGridData(sRecord);
@ -1016,8 +1023,7 @@ public class D2DGridDatabase extends VGridDatabase {
// Resample the data to fit the desired region
float fillV = Float.MAX_VALUE;
ParameterInfo pa = GridParamInfoLookup.getInstance()
.getParameterInfo(mappedModel, "ws");
ParameterInfo pa = modelInfo.getParameterInfo("ws");
if (pa != null) {
fillV = pa.getFillValue();
}
@ -1153,14 +1159,11 @@ public class D2DGridDatabase extends VGridDatabase {
throw new GfeException("Unable to get GFE dao!!", e);
}
List<Integer> fcstTimes = dao.getD2DForecastTimes(dbId);
List<Integer> fcstTimes = dao.getForecastTimes(d2dModelName, refTime);
SortedSet<Date> validTimes = new TreeSet<Date>();
Calendar validTimeCalc = Calendar.getInstance();
Date refTime = dbId.getModelTimeAsDate();
for (Integer fcstTime : fcstTimes) {
validTimeCalc.setTime(refTime);
validTimeCalc.add(Calendar.SECOND, fcstTime.intValue());
validTimes.add(validTimeCalc.getTime());
validTimes.add(new Date(refTime.getTime() + fcstTime
* TimeUtil.MILLIS_PER_SECOND));
}
return validTimes;
}
@ -1214,6 +1217,18 @@ public class D2DGridDatabase extends VGridDatabase {
return gfeParmName;
}
public String getD2DParmName(String gfeParmName) {
String d2dParmName = null;
try {
d2dParmName = ParameterMapper.getInstance().lookupBaseName(
gfeParmName, "gfeParamName");
} catch (MultipleMappingException e) {
statusHandler.handle(Priority.WARN, e.getLocalizedMessage(), e);
d2dParmName = e.getArbitraryMapping();
}
return d2dParmName;
}
public TimeRange getTimeRange(ParmID parmID, Integer fcstHour) {
D2DParm parm = this.gfeParms.get(parmID);
if (parm == null) {
@ -1227,4 +1242,34 @@ public class D2DGridDatabase extends VGridDatabase {
private String compositeName(String parmName, String level) {
return parmName + "_" + level;
}
private static Level getD2DLevel(String gfeLevel) {
String levelName = GridTranslator.getLevelName(gfeLevel);
double[] levelValues = GridTranslator.getLevelValue(gfeLevel);
boolean levelOnePresent = (levelValues[0] != Level
.getInvalidLevelValue());
boolean levelTwoPresent = (levelValues[1] != Level
.getInvalidLevelValue());
Level level = null;
// to have a level 2, must have a level one
try {
if (levelOnePresent && levelTwoPresent) {
level = LevelFactory.getInstance().getLevel(levelName,
levelValues[0], levelValues[1]);
} else if (levelOnePresent) {
level = LevelFactory.getInstance().getLevel(levelName,
levelValues[0]);
} else {
level = LevelFactory.getInstance().getLevel(levelName, 0.0);
}
} catch (CommunicationException e) {
statusHandler.error(e.getLocalizedMessage(), e);
}
if (level == null) {
statusHandler.warn(gfeLevel + " does not map to a D2D level");
}
return level;
}
}

View file

@ -78,6 +78,8 @@ import com.raytheon.uf.edex.core.EDEXUtil;
* SectorId and PhysicalElement.
* Mar 20, 2013 #1774 randerso Refactor to use grid durations from D2DGridDatabase
* Apr 01, 2013 #1774 randerso Moved wind component checking to GfeIngestNotificaionFilter
* Apr 04, 2013 #1787 randerso Added null check to prevent log spamming for parameters
* not included in the parameter info file
*
* </pre>
*

View file

@ -54,6 +54,8 @@ import com.raytheon.uf.common.time.util.TimeUtil;
* 02/27/2008 879 rbell Added compareTo(TimeRange)
* 03/20/2013 #1774 randerso Changed toString to display times even when
* duration is 0, use TimeUtil constants.
* 04/04/2013 #1787 randerso Removed a bunch of isValid checks to the logic
* works as intended by the original A1 implementation.
*
* </pre>
*
@ -64,7 +66,7 @@ import com.raytheon.uf.common.time.util.TimeUtil;
* starting/ending time, or a time and a duration. If the duration is positive
* (or zero), then the specified time is the start time. If the duration is
* negative, then the specified time is the end time as shown in the design
* document*.
* document.
*
* TimeRanges are generally used to define a valid time range for data files.
* TimeRange components (start time, end time, and duration) may be retrieved.
@ -314,11 +316,7 @@ public class TimeRange implements Serializable, Comparable<TimeRange>,
* @return the duration
*/
public long getDuration() {
if (isValid()) {
return end.getTime() - start.getTime();
} else {
return 0L;
}
return end.getTime() - start.getTime();
}
/*
@ -368,16 +366,13 @@ public class TimeRange implements Serializable, Comparable<TimeRange>,
* @return
*/
public boolean contains(Date time) {
if (!this.isValid()) {
return false;
}
if (getDuration() != 0) {
// the end time is not part of the time range (hence the < operator)
return time.getTime() >= start.getTime()
&& time.getTime() < end.getTime();
} else {
return time.equals(start); // Special case for zero duration time
// range
// Special case for zero duration time range
return time.equals(start);
}
}
@ -388,7 +383,14 @@ public class TimeRange implements Serializable, Comparable<TimeRange>,
* @param time
* the time to be included
*/
@Deprecated
public void extend(Date time) {
// TODO: remove this method as it is the only method other than the
// setters required for dynamic serialization that modify a TimeRange
// The original intent was for this class to be immutable.
// I found no Java code calling this method but it's difficult to
// determine if it's called from Python since extend is a build in
// method on lists
if (!this.isValid()) {
return;
}
@ -409,10 +411,6 @@ public class TimeRange implements Serializable, Comparable<TimeRange>,
* @return true if a time range is contained within the range
*/
public boolean contains(TimeRange timeRange) {
if (!this.isValid()) {
return false;
}
if (getDuration() == 0) {
return this.equals(timeRange);
} else if (timeRange.getDuration() == 0) {
@ -433,10 +431,6 @@ public class TimeRange implements Serializable, Comparable<TimeRange>,
* @return true if the time ranges are adjacent
*/
public boolean isAdjacentTo(TimeRange timeRange) {
if (!this.isValid()) {
return false;
}
return start.equals(timeRange.end) || end.equals(timeRange.start);
}
@ -452,10 +446,6 @@ public class TimeRange implements Serializable, Comparable<TimeRange>,
* @return true if the time range overlaps
*/
public boolean overlaps(TimeRange timeRange) {
if (!this.isValid()) {
return false;
}
if (timeRange.contains(start) || contains(timeRange.getStart())) {
return true;
} else {
@ -555,9 +545,6 @@ public class TimeRange implements Serializable, Comparable<TimeRange>,
*/
@Override
public TimeRange clone() {
if (!this.isValid()) {
return new TimeRange();
}
return new TimeRange(this.start, this.end);
}