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:
commit
30e77171ab
7 changed files with 237 additions and 302 deletions
|
@ -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>
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue