def sampleAtTimesofGridB(gridA, gridB, matchformat="yyyyMMddhhmm"): """ A function to programatically sample gridA at times of gridB, similar to idv gui but the format decides what type type is picked. one other application of this utility is when there are a lot of times where gui selection in IDV becomes tedious. """ from visad import RealType from visad import Gridded1DDoubleSet from visad import FieldImpl from visad import FunctionType from visad import VisADException timeSetA = GridUtil.getTimeSet(gridA) timeSetB = GridUtil.getTimeSet(gridB) timesA = getSampleTimesInFormat(gridA, str(matchformat)) timesB = getSampleTimesInFormat(gridB, str(matchformat)) indicesA = returnMatches(timesA, timesB) timevalsA = timeSetA.getSamples()[0] subsetTimeValuesA = [timevalsA[i] for i in indicesA] newTimesA = Gridded1DDoubleSet(RealType.Time, [subsetTimeValuesA], len(subsetTimeValuesA), None, timeSetA.getSetUnits(), None) subsetgridA = FieldImpl( FunctionType(RealType.Time, gridA.getSample(0).getType()), newTimesA) for i in range(len(subsetTimeValuesA)): subsetgridA.setSample(i, gridA[indicesA[i]]) return subsetgridA
def makeTimeComposite(variable, avgvariable, minvalue, maxvalue): """ Make a time composite of grid supplied(variable) between min max ranges of a 1d avg variable supplied. """ from visad import FunctionType from visad import FieldImpl from visad import RealType from visad import Gridded1DDoubleSet from visad import VisADException from ucar.unidata.util.Misc import getAverage timeSet = GridUtil.getTimeSet(avgvariable) newTimeIndexList = java.util.ArrayList() newTimeValues = [] for i in range(timeSet.getLength()): avg = getAverage(avgvariable.getSample(i).getFloats()[0]) if minvalue < avg <= maxvalue: newTimeIndexList.add(Integer(i)) newTimeValues.append(timeSet[i].getValue()) print(len(newTimeIndexList)) if (len(newTimeIndexList) < 1): raise VisADException("No Matches found to make a time composite") newTimes = Gridded1DDoubleSet(RealType.Time, [newTimeValues], len(newTimeValues), None, timeSet.getSetUnits(), None) compvariable = FieldImpl( FunctionType(RealType.Time, variable.getSample(0).getType()), newTimes) for i in range(len(newTimeValues)): compvariable.setSample(i, variable[newTimeIndexList[i]]) return compvariable
def getSamplesAtTimes(grid, year=None, season=None, mon=None, day=None, hour=None, min=None, sec=None, ms=None): """ Samples a grid at specified time periods, multiple arguments can be used in complex sampling eg.., using hour = 5 would return all samples corresponding to 5 am, further specifing year = 2008 would give samples at 5am in year 2008 """ from visad import RealType from visad import Gridded1DDoubleSet from visad import FieldImpl from visad import FunctionType from visad import VisADException if (str(mon) != "None" and str(season) != "None"): raise VisADException("One of Month or Season can be used, not both") timeSet = GridUtil.getTimeSet(grid) indices = getSampleTimeIndices(grid, year, season, mon, day, hour, min, sec, ms) timevals = timeSet.getSamples()[0] subsetTimeValues = [timevals[i] for i in indices] newTimes = Gridded1DDoubleSet(RealType.Time, [subsetTimeValues], len(subsetTimeValues), None, timeSet.getSetUnits(), None) subsetgrid = FieldImpl( FunctionType(RealType.Time, grid.getSample(0).getType()), newTimes) for i in range(len(subsetTimeValues)): subsetgrid.setSample(i, grid[indices[i]]) return subsetgrid
def makeTimeSequence(g): """ Merge a set of single time grids/images into a time sequence """ from visad import FunctionType, FieldImpl, Gridded1DDoubleSet, QuickSort from jarray import array domain = getDomainSet(g[0]) dt = getDomainType(g[0]) v=[getDomain(g[i]).indexToDouble([0,])[0][0] for i in range(len(g))] va = array(v,'d') index = QuickSort.sort(va) ft=FunctionType(dt, getRangeType(g[0])) fld=FieldImpl(ft,Gridded1DDoubleSet.create(dt,va,None,domain.getSetUnits()[0],None)) for i in range(len(g)): fld.setSample(i,g[index[i]].getSample(0),0) return fld
def subsetGridTimes(gridA, gridB): """ A function to subset gridA by times of gridB. duplicate of another function subsetAtTimesofB """ timeSet = GridUtil.getTimeSet(gridB) indices = getSampleTimeIndices(grid, year, season, mon, day, hour, min, sec, ms) timevals = timeSet.getSamples()[0] subsetTimeValues = [timevals[i] for i in indices] newTimes = Gridded1DDoubleSet(RealType.Time, [subsetTimeValues], len(subsetTimeValues), None, timeSet.getSetUnits(), None) subsetgrid = FieldImpl( FunctionType(RealType.Time, grid.getSample(0).getType()), newTimes) for i in range(len(subsetTimeValues)): subsetgrid.setSample(i, grid[indices[i]]) return subsetgrid
def makeFlatFieldSequence(sequence): """Turn list of _MappedGeoGridFlatField's into a FieldImpl with time domain that is suitable for displaying. This will work if the flatfield's have a time associated with them via getMetadataMap, but if that doesn't work we're out of luck because a plain old FlatField doesn't have any timestamp. How do handle we that case? Do we put in fake timestamps so the data can at least get displayed still? """ from ucar.unidata.data import DataUtil from ucar.visad import Util from visad import FunctionType from visad import RealType from visad import DateTime dateTimes = [] try: for ff in sequence: if ff.geogrid.getCoordinateSystem().hasTimeAxis1D(): timeAxis = ff.geogrid.getCoordinateSystem().getTimeAxis1D() dateTimes.append(DataUtil.makeDateTimes(timeAxis)[0]) else: # fix for ABI data / data with no time coord: just return plain FF # this will allow data to get displayed, but w/o time info return ff except AttributeError: # no geogrid ... try to read from getMetadataMap if sequence[0].getMetadataMap().get('times'): # this was a _MappedGeoGridFlatField for ff in sequence: # should be a visad.DateTime: timeStr = ff.getMetadataMap().get('times')[0].toString() dateTimes.append(DateTime.createDateTime(timeStr)) elif sequence[0].getMetadataMap().get('nominal-time'): # this was a _MappedAreaImageFlatField for ff in sequence: time = ff.getMetadataMap().get('nominal-time') dateTimes.append(time) timeSet = Util.makeTimeSet(dateTimes) ftype = FunctionType(RealType.Time, ff.getType()) fi = FieldImpl(ftype, timeSet) for i, ff in enumerate(sequence): fi.setSample(i, ff) return fi
def mergeTimeSequences(g): """ Merge a set of time sequences of grids/images into a single time sequence. All grids/images must have the same parameter name """ from visad import FunctionType, FieldImpl, Gridded1DDoubleSet, Set, Unit domain = getDomainSet(g[0]) newDomain = domain dt = getDomainType(g[0]) rt = getRangeType(g[0]) for i in range(1,len(g)): newDomain = newDomain.merge1DSets(getDomainSet(g[i])) ft=FunctionType(dt, rt) fld=FieldImpl(ft,newDomain) for i in range(len(g)): oldDomain = getDomainSet(g[i]) values = oldDomain.getDoubles(1) values = Unit.convertTuple(values, oldDomain.getSetUnits(), newDomain.getSetUnits()) index = newDomain.doubleToIndex(values) for j in range(len(index)): if (index[j] >= 0): fld.setSample(index[j], g[i].getSample(j), 0) return fld
def stdMon(grid): """ Create monthly standard deviations from a grid of monthly data over a period of years. The number of timesteps must be a multiple of 12. """ from visad import VisADException from visad import Gridded1DDoubleSet from visad import FunctionType from visad import FieldImpl from visad import RealType timeSet = GridUtil.getTimeSet(grid) numT = timeSet.getLength() if (numT % 12 > 0): raise VisADException("Number of times must be a multiple of 12") numYears = numT / 12 days = [[0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]] units = [Util.parseUnit("days since 0001-01-01 00:00")] newTimes = Gridded1DDoubleSet(RealType.Time, days, 12, None, units, None) stdev = FieldImpl(FunctionType(RealType.Time, grid.getSample(0).getType()), newTimes) for month in range(12): a = GridMath.applyFunctionOverTime(grid, GridMath.FUNC_STDEV, month, 12, 0) stdev.setSample(month, a, 0) return stdev
def package(original, result): """ Put 'result' back into a FieldImpl using the time domain from 'original'. Args: original: the original argument to the VIIRS formula being called result: the result of the MultiSpectralDataSource methods called by the current VIIRS formula Returns: FieldImpl with proper time domain (so that e.g. IDV's %timestamp% macro will work properly) """ from visad import FunctionType from visad import FieldImpl from visad import RealType if GridUtil.isTimeSequence(original): ftype = FunctionType(RealType.Time, result.getType()) fieldimpl = FieldImpl(ftype, original.getDomainSet()) fieldimpl.setSample(0, result) return fieldimpl else: # just return the plain flatfield if original wasn't a fieldimpl # (needed to make loadJPSSImage work) return result
def ddt(grid, timegradunit): """ compute tendency (time derivative) using forward difference, units of returned grid are units of grid per timegradient unit timegradient unit can be month, day, hour, minute, seconds """ from visad import Real from visad import FunctionType from visad import FieldImpl from visad import RealType from visad import Gridded1DDoubleSet from ucar.visad.data import CalendarDateTime from visad import CommonUnit from visad import VisADException if (GridUtil.isTimeSequence(grid) == 1): newTimeValues = [] timediffs = [] ts = GridUtil.getTimeSet(grid) if (str(timegradunit).lower() in ("mon", "month", "months")): timefactor = 86400.0 * 30 timegradunit = "month" elif (str(timegradunit).lower() in ("day", "d", "days")): timefactor = 86400.0 timegradunit = "day" elif (str(timegradunit).lower() in ("hr", "hour", "hours")): timefactor = 3600.0 timegradunit = "hr" elif (str(timegradunit).lower() in ("m", "min", "minute", "minutes")): timefactor = 60.0 timegradunit = "min" elif (str(timegradunit).lower() in ("s", "sec", "second", "seconds")): timefactor = 1.0 timegradunit = "s" else: raise VisADException( "Requested time gradient unit is ambigious,use month,day,hour etc" ) for i in range(grid.getDomainSet().getLength() - 1): newTimeValues.append((ts[i].getValue() + ts[i + 1].getValue()) / 2) prevtime = float(ts[i].getValue(CommonUnit.secondsSinceTheEpoch)) nexttime = float(ts[i + 1].getValue( CommonUnit.secondsSinceTheEpoch)) timediffs.append((nexttime - prevtime) / timefactor) newTimes = Gridded1DDoubleSet(RealType.Time, [newTimeValues], len(newTimeValues), None, ts.getSetUnits(), None) ddtgrid = FieldImpl( FunctionType(RealType.Time, grid.getSample(0).getType()), newTimes) for i in range(grid.getDomainSet().getLength() - 1): diff = (grid.getSample(i + 1) - grid.getSample(i)).divide( Real(timediffs[i])) ddtgrid.setSample(i, diff) unitname = str( GridUtil.getParamType(grid).getComponent(0).getDefaultUnit()) print("[" + unitname + "]/" + str(timegradunit)) newunit = Util.parseUnit("(" + unitname + ")/" + str(timegradunit)) newType = Util.makeRealType("ddt of " + getVarName(grid), newunit) else: raise VisADException( "Well, this data is not a time series, hard to do a time derivative!" ) return GridUtil.setParamType(ddtgrid, newType, 0)
def createTimeMeans(grid, meanType="None"): """ Create time mean of a grid at periods specified by type. meanType can be yearly, monthly, daily, hourly, minutes, seconds """ from visad import Real from visad import Gridded1DDoubleSet from visad import FieldImpl from visad import FunctionType from visad import RealType from visad import VisADException if (str(meanType).lower() in ("year", "yr", "years", "yearly")): searchFormat = "yyyy" elif (str(meanType).lower() in ("mon", "month", "months", "monthly")): searchFormat = "MM" elif (str(meanType).lower() in ("day", "d", "days", "daily")): searchFormat = "dd" elif (str(meanType).lower() in ("hr", "hour", "hours", "hourly")): searchFormat = "hh" elif (str(meanType).lower() in ("m", "min", "minute", "minutes", "minutely")): searchFormat = "mm" elif (str(meanType).lower() in ("s", "sec", "second", "seconds")): searchFormat = "ss" else: raise VisADException( "Unrecognized time mean type, use yearly or monthly etc") alltimes = getSampleTimesInFormat(grid, searchFormat) timeSet = GridUtil.getTimeSet(grid) timeset = GridUtil.getTimeSet(grid).getSamples()[0] timevalues = [i for i in timeset] oldtime = alltimes[0] temptime = 0 count = 0 newtimelist = [] for currt, tv, i in zip(alltimes, timevalues, range(len(alltimes))): #values are always accumulated next time if currt == oldtime: #takes care of multiple times,first time,last time temptime = temptime + tv count = count + 1 if (i == (len(alltimes) - 1)): newtimeval = temptime / count newtimelist.append(newtimeval) else: #prev values are accumulated join to list newtimeval = temptime / count newtimelist.append(newtimeval) count = 1 temptime = tv oldtime = currt if (i == (len(alltimes) - 1)): newtimelist.append(temptime) #create new time set newTimes = Gridded1DDoubleSet(RealType.Time, [newtimelist], len(newtimelist), None, timeSet.getSetUnits(), None) newdatalist = FieldImpl( FunctionType(RealType.Time, grid.getSample(0).getType()), newTimes) timindices = range(len(newtimelist)) oldtime = alltimes[0] tempdata = grid.getSample(0).multiply(Real(0.0)) count = 0 newind = 0 for currt, i in zip(alltimes, range(len(alltimes))): #values are always accumulated next time if currt == oldtime: #takes care of multiple times,first time,last time tempdata = tempdata.add(grid.getSample(i)) count = count + 1 if (i == (len(alltimes) - 1)): newdatalist.setSample(newind, tempdata.divide(Real(count))) newind = newind + 1 else: #prev values are accumulated join to list newdatalist.setSample(newind, tempdata.divide(Real(count))) newind = newind + 1 count = 1 tempdata = grid.getSample(i) oldtime = currt if (i == (len(alltimes) - 1)): newdatalist.setSample(newind, tempdata.divide(Real(count))) newParamName = "Time Mean " + str( Util.cleanTypeName(GridUtil.getParamType(grid))) return newName(newdatalist, newParamName)
def animation(data, width=400, height=500, title="VisAD Animation"): """ Quick plot of an animation. <data> is a list/tuple of iamges to animate. <width> and <height> are the size, and <title> is the label for the titlebar. Returns a reference to the display. """ num_frames = len(data) frames = RealType.getRealType("frames") frames_type = RealTupleType(frames) image_type = data[0].getType() ndom = domainDimension(data[0]) if ndom != 2: print "domain dimension must be 2!" return None dom_1 = RealType.getRealType(domainType(data[0], 0)) dom_2 = RealType.getRealType(domainType(data[0], 1)) nrng = rangeDimension(data[0]) if (nrng != 3) and (nrng != 1): print "range dimension must be 1 or 3" return None # now create display scalar maps maps = None rng_1 = rangeType(data[0], 0) if nrng == 3: rng_2 = rangeType(data[0], 1) rng_3 = rangeType(data[0], 2) rng_red = None if (rng_1 == "Red"): rng_red = rng_1 if (rng_2 == "Red"): rng_red = rng_2 if (rng_3 == "Red"): rng_red = rng_3 rng_green = None if (rng_1 == "Green"): rng_green = rng_1 if (rng_2 == "Green"): rng_green = rng_2 if (rng_3 == "Green"): rng_green = rng_3 rng_blue = None if (rng_1 == "Blue"): rng_blue = rng_1 if (rng_2 == "Blue"): rng_blue = rng_2 if (rng_3 == "Blue"): rng_blue = rng_3 if (rng_red is None) or (rng_green is None) or (rng_blue is None): print "3 Range components must be Red, Green and Blue" else: maps = subs.makeMaps(dom_1, "x", dom_2, "y", RealType.getRealType(rng_red), "red", RealType.getRealType(rng_green), "green", RealType.getRealType(rng_blue), "blue") else: maps = subs.makeMaps(dom_1, "x", dom_2, "y", RealType.getRealType(rng_1), "rgb") frame_images = FunctionType(frames_type, image_type) frame_set = makeDomain(frames, 0, num_frames - 1, num_frames) frame_seq = FieldImpl(frame_images, frame_set) for i in range(0, num_frames): frame_seq.setSample(i, data[i]) disp = subs.makeDisplay(maps) animap = ScalarMap(frames, Display.Animation) disp.addMap(animap) refimg = subs.addData("VisAD_Animation", frame_seq, disp) widget = AnimationWidget(animap, 500) subs.setAspectRatio(disp, float(width) / float(height)) myAnimFrame(disp, widget, width, height, "Animation") return disp