diff --git a/cave/build/.pydevproject b/cave/build/.pydevproject index faf12629d9..f4a659751e 100644 --- a/cave/build/.pydevproject +++ b/cave/build/.pydevproject @@ -2,6 +2,6 @@ -python 2.5 +python 2.7 Default diff --git a/edexOsgi/build.edex/esb/data/utility/common_static/base/python/gfe/TimeRange.py b/edexOsgi/build.edex/esb/data/utility/common_static/base/python/gfe/TimeRange.py index 2cd383d2a3..8ce0fcc277 100644 --- a/edexOsgi/build.edex/esb/data/utility/common_static/base/python/gfe/TimeRange.py +++ b/edexOsgi/build.edex/esb/data/utility/common_static/base/python/gfe/TimeRange.py @@ -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() diff --git a/edexOsgi/build.edex/esb/data/utility/edex_static/base/smartinit/Init.py b/edexOsgi/build.edex/esb/data/utility/edex_static/base/smartinit/Init.py index be5b6c6a1e..2b69ed97f1 100644 --- a/edexOsgi/build.edex/esb/data/utility/edex_static/base/smartinit/Init.py +++ b/edexOsgi/build.edex/esb/data/utility/edex_static/base/smartinit/Init.py @@ -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 diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/db/dao/GFED2DDao.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/db/dao/GFED2DDao.java index 5f3ae9bd82..4fb1d08c31 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/db/dao/GFED2DDao.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/db/dao/GFED2DDao.java @@ -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. * * * @@ -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 getD2DForecastTimes(DatabaseID dbId) + public List 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 rawTimes = queryByD2DParmId(id, s); + SortedMap 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 queryByD2DParmId(ParmID id, Session s) + public SortedMap 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(); - } - - 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 results = modelQuery.list(); - - Integer modelId = null; - if (results.size() == 0) { - return new TreeMap(); - } 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 timeResults = timeQuery.list(); - - if (timeResults.isEmpty()) { - return new TreeMap(); - } + List firstTry = (List) this.queryByCriteria(query); SortedMap dataTimes = new TreeMap(); - 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 secondTry = (List) 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 queryFcstHourByD2DParmId(ParmID id) + public List queryFcstHourByParmId(String d2dModelName, + Date refTime, String d2dParmName, Level d2dLevel) throws DataAccessLayerException { List timeList = new ArrayList(); 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 results = queryByD2DParmId(uWindId, - s); - List uTimeList = new ArrayList(results.size()); - for (Integer o : results.keySet()) { - uTimeList.add(o); - } - - ParmID vWindId = new ParmID(idWindMatcher.replaceAll("vW")); - results = queryByD2DParmId(vWindId, s); - Set vTimeList = new HashSet(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 sTimeList = new ArrayList(results.size()); - for (Integer o : results.keySet()) { - sTimeList.add(o); - } - - ParmID dWindId = new ParmID(idWindMatcher.replaceAll("wd")); - results = queryByD2DParmId(dWindId, s); - Set dTimeList = new HashSet(results.size(), 1); - for (Integer o : results.keySet()) { - dTimeList.add(o); - } - - for (Integer tr : sTimeList) { - if (dTimeList.contains(tr)) { - timeList.add(tr); - } - } - } else { - SortedMap results = queryByD2DParmId(id, s); - for (Integer o : results.keySet()) { - timeList.add(o); - } + SortedMap 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 getD2DModelRunTimes(String d2dModelName, int maxRecords) + public List getModelRunTimes(String d2dModelName, int maxRecords) throws DataAccessLayerException { DatabaseQuery query = new DatabaseQuery(GridRecord.class.getName()); query.addDistinctParameter(REF_TIME); diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/database/D2DGridDatabase.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/database/D2DGridDatabase.java index b840e1cc36..594b8177d0 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/database/D2DGridDatabase.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/database/D2DGridDatabase.java @@ -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 * * * @@ -167,8 +169,7 @@ public class D2DGridDatabase extends VGridDatabase { try { GFED2DDao dao = new GFED2DDao(); - List result = dao.getD2DModelRunTimes(d2dModelName, - maxRecords); + List result = dao.getModelRunTimes(d2dModelName, maxRecords); List dbInventory = new ArrayList(); 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 fcstHrToTimeRange, String... components) { this.parmId = parmId; @@ -222,6 +225,8 @@ public class D2DGridDatabase extends VGridDatabase { for (Entry 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 compInv = dao - .queryFcstHourByD2DParmId(compPid); + List 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 fcstTimes = dao.getD2DForecastTimes(dbId); + List fcstTimes = dao.getForecastTimes(d2dModelName, refTime); SortedSet validTimes = new TreeSet(); - 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; + } } diff --git a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/notify/GfeIngestNotificationFilter.java b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/notify/GfeIngestNotificationFilter.java index 9e0caed7b8..cf101ef2f7 100644 --- a/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/notify/GfeIngestNotificationFilter.java +++ b/edexOsgi/com.raytheon.edex.plugin.gfe/src/com/raytheon/edex/plugin/gfe/server/notify/GfeIngestNotificationFilter.java @@ -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 * * * diff --git a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/TimeRange.java b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/TimeRange.java index 5da7b72323..c8de72145f 100644 --- a/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/TimeRange.java +++ b/edexOsgi/com.raytheon.uf.common.time/src/com/raytheon/uf/common/time/TimeRange.java @@ -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. * * * @@ -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, * @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, * @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, * @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, * @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, * @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, * @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, */ @Override public TimeRange clone() { - if (!this.isValid()) { - return new TimeRange(); - } return new TimeRange(this.start, this.end); }