def _getGaps(self, WEName, trList): fullHazardInv = self._getWEInventory(WEName) gaps = [] for timeRange in trList: # Convert Java TimeRange to Python for comparisons if not isinstance(timeRange, TimeRange): timeRange = TimeRange(timeRange) hazInv = [] for h in fullHazardInv: if timeRange.overlaps(h): hazInv.append(h) # check for empty inventory if len(hazInv) == 0: # no grids at all gaps.append(timeRange) continue # see if we have a gap at the beginning if timeRange.startTime() < hazInv[0].startTime(): tr = TimeRange(timeRange.startTime(), hazInv[0].startTime()) gaps.append(tr) # Find any gaps in the middle of the inventory for i in range(len(hazInv) - 1): if hazInv[i].endTime() != hazInv[i+1].startTime(): gapTR = TimeRange(hazInv[i].endTime(), hazInv[i+1].startTime()) gaps.append(gapTR) # see if we have a gap at the end of the inventory if timeRange.endTime() > hazInv[-1].endTime(): tr = TimeRange(hazInv[-1].endTime(), timeRange.endTime()) gaps.append(tr) return gaps
def _setupHazardsInventory(self, weName, trList): # see if the element exists yet, if not, make a new grid # This is a painful way just to see if the grid exists # but all other techniques fail for temporary weather elements now = current() yesterday = now - (24 * 3600) # one day ago later = now + 10 * 24 * 3600 # 10 days from now timeRange = TimeRange(yesterday, later).toJavaObj() try: gridInfo = self.getGridInfo(MODEL, weName, LEVEL, timeRange) except: # this means the WE does not exist, so make a grid if len(trList) <= 0: return for tr in trList: self._makeEmptyHazardGrid(weName, tr) return # fill any gaps in the inventory gapList = self._getGaps(weName, trList) for g in gapList: self._makeEmptyHazardGrid(weName, g) # Split the grids at the timeRange boundaries unix_now = now.unixTime() for tr in trList: # If tr is a java timerange, convert it to a python TimeRange if not isinstance(tr, TimeRange): tr = TimeRange(tr) end = tr.endTime().unixTime() if end > unix_now: # parm.splitTR() will split timeRanges with non-zero minutes # to the next hour. So, truncate start and end times to the # previous hour and then split start = tr.startTime().unixTime() start = int(start / 3600) * 3600 end = int(end / 3600) * 3600 roundedTR = TimeRange(AbsTime(start), AbsTime(end)).toJavaObj() parm = self.getParm(MODEL, weName, LEVEL) self.splitCmd([weName], roundedTR) return
def _addHazard(self, weName, timeRange, addHaz, mask, combine=1): # Python TimeRanges are easy to compare. # Java methods require Java TimeRanges. # Make sure we have one of each. if isinstance(timeRange, JavaWrapperClass): pyTimeRange = timeRange timeRange = timeRange.toJavaObj() else: pyTimeRange = TimeRange(timeRange) # refuse to make new grids that are more than one hour in the past if pyTimeRange.endTime().unixTime() < current().unixTime() - HOUR_SECONDS(): msg = "skipped time range creation: %s < %s" % (pyTimeRange.endTime().string(), current().string()) return # set up the inventory first self._setupHazardsInventory(weName, [timeRange]) # get the inventory trList = self._getWEInventory(weName, timeRange, asJava=True) # coerce mask into a boolean array if it isn't already if not (isinstance(mask, numpy.ndarray) and mask.dtype==numpy.bool): mask = numpy.array(mask, dtype=numpy.bool) for tr in trList: # get the grid of index values and list of keys those indices select byteGrid, hazKey = self.getGrids(MODEL, weName, LEVEL, tr, mode="First", cache=0) if isinstance(hazKey, str): hazKey = eval(hazKey) # Eliminate keys that aren't in the grid from the list. uniqueKeys = self._getUniqueKeys(byteGrid, hazKey, mask) for uKey in uniqueKeys: # Figure out what the new key is if combine: newKey = self._makeNewKey(uKey, addHaz) else: #replace newKey = addHaz # Find the index number for the old key oldIndex = self.getIndex(uKey, hazKey) # Find the index number for the new key (newKey is added if not in hazKey) newIndex = self.getIndex(newKey, hazKey) # calculate the mask - intersection of mask and oldIndex values editMask = (byteGrid==oldIndex) & mask # poke in the new values byteGrid[editMask] = newIndex # Save the updated byteGrid and hazKey if weName == ELEMENT: self.createGrid(MODEL, ELEMENT, "DISCRETE", (byteGrid, hazKey), tr, discreteOverlap=1, discreteAuxDataLength=4) else: # it's a temporary WE - special key hazKey = ["<None>", addHaz] hazKeyDesc = self._addHazardDesc(hazKey) self.createGrid(MODEL, weName, "DISCRETE", (byteGrid, hazKey), tr, discreteOverlap=0, discreteAuxDataLength=4, discreteKeys=hazKeyDesc, defaultColorTable="YesNo") # remove any grids that are completely in the past self._removeOldGrids(weName) return
def _separateHazardGrids(self): "Make temporary hazard grids for each hazard subkey." # if any temp hazard grids are loaded, don't separate again if self._tempWELoaded(): return FAIL_REDUNDANT #already separated hazParm, gridData = self._lockHazards() if hazParm is None: return FAIL_LOCK # unavailable # get a collection of distinct Java TimeRange objects trSet = set() for gd in gridData: trSet.add(gd.getGridTime()) # Create a set of temporary weather element names weNameSet = set() for tr in trSet: # Get the index grid and key list for the real Hazards element byteGrid, hazKey = self.getGrids(MODEL, ELEMENT, LEVEL, tr, mode="First") if isinstance(hazKey, str): hazKey = eval(hazKey) # Only work with the keys that have points in the grid uniqueKeys = self._getUniqueKeys(byteGrid, hazKey) if len(uniqueKeys) > 0: # build list of split hazKeys for use in loop below splitHazKeys = [] for haz in hazKey: splitHazKeys.append(self._getSubKeys(haz)) for uKey in uniqueKeys: if uKey == "<None>": continue # split the current key into its subkeys subKeys = self._getSubKeys(uKey) for subKey in subKeys: # make the temporary name weName = self._makeTempWEName(subKey) # make the mask - find all areas that contain the subKey mask = numpy.zeros(byteGrid.shape, dtype=numpy.bool) for hazIndex in range(len(hazKey)): if subKey in splitHazKeys[hazIndex]: mask |= (byteGrid==hazIndex) # make the grid self._addHazard(weName, tr, subKey, mask) pytr = TimeRange(tr) logmsg = " ".join(["Separate", weName, self._printTime(pytr.startTime().unixTime()), self._printTime(pytr.endTime().unixTime()), subKey]) LogStream.logEvent(logmsg) # save the weNames for later weNameSet.add(weName) # Combine time ranges for the temporary weather elements we created self._consolidateTimes(weNameSet) return SUCCESS
def _separateHazardGrids(self): "Make temporary hazard grids for each hazard subkey." # if any temp hazard grids are loaded, don't separate again if self._tempWELoaded(): return FAIL_REDUNDANT #already separated hazParm, gridData = self._lockHazards() if hazParm is None: return FAIL_LOCK # unavailable # get a collection of distinct Java TimeRange objects trSet = set() for gd in gridData: trSet.add(gd.getGridTime()) # Create a set of temporary weather element names weNameSet = set() for tr in trSet: # Get the index grid and key list for the real Hazards element byteGrid, hazKey = self.getGrids(MODEL, ELEMENT, LEVEL, tr, mode="First") if isinstance(hazKey, str): hazKey = eval(hazKey) # Only work with the keys that have points in the grid uniqueKeys = self._getUniqueKeys(byteGrid, hazKey) if len(uniqueKeys) > 0: # build list of split hazKeys for use in loop below splitHazKeys = [] for haz in hazKey: splitHazKeys.append(self._getSubKeys(haz)) for uKey in uniqueKeys: if uKey == "<None>": continue # split the current key into its subkeys subKeys = self._getSubKeys(uKey) for subKey in subKeys: # make the temporary name weName = self._makeTempWEName(subKey) # make the mask - find all areas that contain the subKey mask = numpy.zeros(byteGrid.shape, dtype='bool') for hazIndex in range(len(hazKey)): if subKey in splitHazKeys[hazIndex]: mask |= (byteGrid==hazIndex) # make the grid self._addHazard(weName, tr, subKey, mask) pytr = TimeRange(tr) logmsg = " ".join(["Separate", weName, self._printTime(pytr.startTime().unixTime()), self._printTime(pytr.endTime().unixTime()), subKey]) LogStream.logEvent(logmsg) # save the weNames for later weNameSet.add(weName) # Combine time ranges for the temporary weather elements we created self._consolidateTimes(weNameSet) return SUCCESS