Skip to content

Instantly share code, notes, and snippets.

@julienchastang
Created April 27, 2015 16:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save julienchastang/c7589f5f8b2fbbd688b3 to your computer and use it in GitHub Desktop.
Save julienchastang/c7589f5f8b2fbbd688b3 to your computer and use it in GitHub Desktop.
IDV Jython Example
setOffScreen(1)
idv.getStateManager().setViewSize(java.awt.Dimension(1000,1000)) #1000 x 1000 pixels
#Datasource (this can be made into a prompt for multiple model files)
dsStr = java.lang.String("/disk7/rkowch/IDV/mitfluids/netcdf/")
ModelFile = java.lang.String("IDVmitmodel2.nc")
dsStr = java.lang.String(dsStr.concat(ModelFile))
ds = makeDataSource(dsStr,"netcdf.grid")
print "Datasource Created"
print " "
#Get information about available time frames
AllTimes = ds.getAllDateTimes() #<--A list of all times
AllTimesSize = AllTimes.size() #<--Integer number of frames (first one is 0)
FirstTime = AllTimes.get(0)
LastTime = AllTimes.get(AllTimesSize - 1)
print "Number of Frames: ",AllTimesSize
print "First Time Frame: ",FirstTime
print " Last Time Frame: ",LastTime
print " "
#Prompt user for time(s)
OneOrMoreTimesChoice = int(raw_input(
"One time frame (0) or multiple time frames (1)? "))
print " "
if OneOrMoreTimesChoice == 0:
FrameOne = int(raw_input("Which time frame? "))
elif OneOrMoreTimesChoice == 1:
FrameOne = int(raw_input("Enter first frame: "))
FrameTwo = int(raw_input("Enter final frame: "))
print " "
#Update times list
#Remove times before/after selected frame/interval
for i in range(0,FrameOne):
RemovedTime = AllTimes.remove(0)
if OneOrMoreTimesChoice == 0: #No time interval
FrameTwo = FrameOne #in this case
for j in range((FrameTwo + 1),AllTimesSize):
NewTimesSize = AllTimes.size()
RemovedTime = AllTimes.remove(NewTimesSize - 1)
SelectedTimes = AllTimes
SelectedTimesSize = SelectedTimes.size()
print "New Size of Times Array = ",SelectedTimesSize
FirstElement = AllTimes.get(0)
if SelectedTimesSize > 1:
LastElement = SelectedTimes.get(SelectedTimesSize - 1)
print "First Time selected ------> ",FirstElement
print "Last Time selected -------> ",LastElement
elif SelectedTimesSize == 1:
print "Time selected ------> ",FirstElement
print " "
#A DataChoice and DataSelection is created for each of the display
#controls. The DataSelection is set with the specified time frame/interval.
#The DataChoice selects each field that will be rendered. The available DataChoice
#objects are selected through each field's coded ID. However, the best way to
#select these IDs are through the Master List of DataChoices defined 'MasterListChs'.
#For this cylinder collapse model NetCDF file, notable IDs are below:
# flowvectors = Flow Vectors (from U & V)
# windspeed = Speed (from U & V)
# relvort = Relative Vorticity (from U & V)
# absvort = Absolute Vorticity (from U & V)
# U = U
# V = V
# W = W
# Temp = Potential Temperature
dsID = ds.getUniqueId() # A DataChoice object is created
ObjID = ds.getProperty(dsID) # here, which is set before each
DataChce = ds.findDataChoice(ObjID) # chosen field is rendered.
#Create a DataSelection object, and set it with the specified
#time frame/interval.
DataSel = ds.getDataSelection()
DataSel.setTimes(SelectedTimes)
#Set the DataSelection with a specific area of the grid to be loaded
#into the bounding box (e.g. Northern Hemisphere on the GFS model).
#BoundBox format is: ( MaxLat , MinLon , MinLat , MaxLon ).
import ucar.unidata.data.GeoLocationInfo
GeoSel = DataSel.getGeoSelection(1)
BoundBox = ucar.unidata.data.GeoLocationInfo(1.0,0.0,0.0,1.0)
GeoSel.setBoundingBox(BoundBox)
DataSel.setGeoSelection(GeoSel)
#Create a list 'MasterListChs' that contains all available DataChoice objects.
#NOTE: This list is the best way to select a DataChoice, by using its
# index in the list, rather than typing in its coded ID. The ID of any
# field can be found by opening the IDV interactively, loading the
# datasource, and placing the mouse pointer over the field. On the text
# that is displayed, the first line is the ID of the desired field. But,
# many fields, such as flowvectors, do not support the easy "type-in-ID"
# method. It must be selected from the entire list of DataChoice objects.
MasterListChs = ds.getDataChoices()
#print MasterListChs #<=============Use this to print the "long-name" of each
# field that is available for plotting.
#Prompt user for info on creating the 2D plot
Sptinfo = java.lang.String(raw_input("Enter 'field,c-type,vec(y/n),c-colortable,' "))
print " "
FrstChar = 0 #Ask for more info on vectors if: vec(y/n) = y
for i in range(2):
comma = Sptinfo.indexOf(",",FrstChar)
FrstChar = comma + 1
vecs = java.lang.String(Sptinfo.charAt(FrstChar))
if vecs.equals("y") == 1:
Svcinfo = java.lang.String(raw_input("Enter vector parameters\
'color,skip,width,size (~ 8.0)' "))
print " "
else:
Svcinfo = java.lang.String("null,0,0,0,")
Sctinfo = java.lang.String(raw_input("Enter contour\
'interval,base,min,max,width,labels(y/n),' "))
print " "
Svwinfo = java.lang.String(raw_input("Enter 'azimuth,tilt,zoom-factor,' "))
print " "
#Put all inputs from user into lists
vwinfo = [0,0,0]
vcinfo = [0,0,0,0]
ptinfo = [0,0,0,0]
ctinfo = [0,0,0,0,0,0]
MTXgrp = [ctinfo,vwinfo,ptinfo,vcinfo]
STRgrp = [Sctinfo,Svwinfo,Sptinfo,Svcinfo]
for MTX,STR in zip(MTXgrp,STRgrp):
l = len(MTX)
FrstChar = 0
for I in range(l):
comma = STR.indexOf(",",FrstChar)
Sval = str(STR.substring(FrstChar,comma))
if MTX == vwinfo or \
(MTX == ctinfo and I < 4) or \
(MTX == vcinfo and I == 3):
Fval = float(Sval)
if (MTX == vcinfo and I > 0) or \
(MTX == ctinfo and I == 4):
Fval = int(Sval)
if (MTX == vcinfo and I == 0) or \
MTX == ptinfo or \
(MTX == ctinfo and I == 5):
Fval = java.lang.String(Sval)
MTX[I] = Fval
FrstChar = comma + 1
vwinfo[0] = float(str(vwinfo[0])) #First element appears to be stored
#as a string, so this needs to be done.
#DISPLAY: POTENTIAL TEMPERATURE, 2D (COLOR or LINE) CONTOUR PLOT
#================================================================
#Plot Potential Temperature
if ptinfo[0].equals("theta") == 1:
#Set the field to be plotted now
DataChce = MasterListChs.get(2)
#Check field that is currently plotting
DataChceInfo = DataChce.getStringId()
print "Current Field ------>",DataChceInfo
#Set the level by choosing it from the entire list of levels 'LevelList'
LevelList = ds.getAllLevels(DataChce)
LevelListSize = LevelList.size()
FirstLevel = LevelList.get(0)
LastLevel = LevelList.get(LevelListSize - 1)
#TRY TO FIND THE LEVEL UNIT AND PRINT IT BELOW IN PLACE OF 'm' ?
print "Available Levels for","2D",DataChceInfo
print "Level 0 =",FirstLevel,"m | Level",(LevelListSize - 1),"=",LastLevel,"m"
LevelChoice = int(raw_input("Please enter desired Level index "))
SelectedLevel = LevelList.get(LevelChoice)
print "Selected Level ------>",SelectedLevel,"m"
print " "
LevelasString = SelectedLevel.toString()
LevelasDouble = java.lang.Double(LevelasString)
import visad
Level = visad.Real(LevelasDouble) # Select the level for this 2D plot
DataChce.setLevelSelection(Level) # Set the level on this 2D plot
#Obtain only the data for the selected time(s)/level,
#create the display, and wait for it to render
if ptinfo[1].equals("color") == 1:
disptype = java.lang.String("planviewcontourfilled")
elif ptinfo[1].equals("line") == 1:
disptype = java.lang.String("planviewcontour")
ThetaDATA = DataChce.getData(DataSel)
dc = createDisplay(disptype,ThetaDATA)
pause()
if ptinfo[1].equals("color") == 1:
#Set up the color table
ThetaColor = idv.getDisplayConventions().getParamColorTable("Temp")
degC = dc.getRawDataUnit() #<--Unit of data (celsius)
ThetaColorRange = idv.getDisplayConventions().getParamRange("Temp",degC)
ThetaColorRange.setMin(ctinfo[2])
ThetaColorRange.setMax(ctinfo[3])
ThetaColor.setRange(ThetaColorRange)
ThetaColor.setTransparency(1.0) #Adjust color transparency
#Apply the color table AND range to the display control
dc.setColorTable(ThetaColor)
dc.setRange(ThetaColorRange)
#Apply some other settings (color bar, display unit, etc.)
dc.setColorScaleVisible(1)
dc.setSettingsDisplayUnit(degC)
#Set the contouring properties (for BOTH color & line options)
contours = idv.getDisplayConventions().findDefaultContourInfo("Temp")
if ptinfo[1].equals("line") == 1:
import ucar.unidata.util.ColorTable
linecolor = ucar.unidata.util.ColorTable()
usercolor = idv.getDisplayConventions().getColor(ptinfo[3])
usercltb = java.util.ArrayList(1)
usercltb.add(0,usercolor)
linecolor.setTable(usercltb)
dc.setColorTable(linecolor)
contours.setInterval(ctinfo[0])
contours.setBase(ctinfo[1])
contours.setMin(ctinfo[2])
contours.setMax(ctinfo[3])
contours.setLineWidth(ctinfo[4])
contours.setIsLabeled(ctinfo[5].equals("y")) #<--Contour labels (Yes/No)
dc.setContourInfo(contours)
#Set the Title of the Display on the Main Screen, and apply all of our
#preferences for this Display Control.
if ptinfo[1].equals("color") == 1:
ThetaDispTemp = java.lang.String("Color Contoured Potential Temperature at Level ")
elif ptinfo[1].equals("line") == 1:
ThetaDispTemp = java.lang.String("Line Contoured Potential Temperature at Level ")
ThetaDispTemp = java.lang.String(ThetaDispTemp.concat(LevelasString))
ThetaDispTemp = java.lang.String(ThetaDispTemp.concat(" m"))
dc.setDisplayListTemplate(ThetaDispTemp)
if ptinfo[1].equals("line") == 1:
dc.setDisplayListColor(usercolor)
else:
ColorYellow = idv.getDisplayConventions().getColor('yellow')
dc.setDisplayListColor(ColorYellow) #<--Title is Yellow for filled contours
dc.applyPreferences()
#DISPLAY: VECTOR PLAN VIEW (FROM U AND V FIELDS), only for COLOR-FILLED Theta
#============================================================================
if ptinfo[2].equals("y") == 1:
#Set the field to be plotted now. This MUST be selected from the
#list of DataChoices. NOTE: Only one DataChoice may be selected at any
#time. Therefore, the object 'DataChce' is simply changed as new fields
#are selected for rendering.
DataChce = MasterListChs.get(8)
#Print current field that is plotting
DataChceInfo = DataChce.getStringId()
print "Current Field ------>",DataChceInfo
#IMPORTANT: The display control for the Vector Plan View requires data
#from all levels in the file. Thus, the level selection must include
#all possible levels when loading. The actual level for the display is set with
#another function. But this might be required just for this NetCDF file only.
FromFirstLevel = DataSel.getFromLevel()
ToLastLevel = DataSel.getToLevel()
DataSel.setLevelRange(FromFirstLevel,ToLastLevel)
DataSel.setTimes(SelectedTimes) #<--should be reset whenever DataChce changes
#Obtain only the data for the selected time(s)/level,
#create the display, and wait for it to render
WindVectorDATA = DataChce.getData(DataSel)
dc = createDisplay('planviewflow',WindVectorDATA)
pause()
#LevelChoice is already selected with the Potential Temperature control above
SelectedLevel = LevelList.get(LevelChoice)
#Set these properties on the vectors: Display Range, Color, Level,
# Size, Skip Factor in XY, and Line Width.
#NOTE: For flow vectors, setting the color is different. This
#display control doesn't use color tables. So the color is set
#through a 'color' object in the method setColor(). Some other features
#in dcTwo are also not available (e.g. Color Bar).
VectorValueRange = dc.getColorRangeFromData() # Display Range
dc.setFlowRange(VectorValueRange)
VectColor = idv.getDisplayConventions().getColor(vcinfo[0]) # Color
dc.setColor(VectColor)
dc.setSettingsLevel(SelectedLevel) # Level
dc.setFlowScale(vcinfo[3]) # Vector Size
dc.setSkipValue(vcinfo[1]) # Skip Factor
dc.setLineWidth(vcinfo[2]) # Line Width
#Set the Title of the Display on the Main Screen, and apply all of our
#preferences for this Display Control.
LevelasString = SelectedLevel.toString() #<--We need the level value in a String
FlowDispTemp = java.lang.String("Flow Vectors at Level ")
FlowDispTemp = java.lang.String(FlowDispTemp.concat(LevelasString))
FlowDispTemp = java.lang.String(FlowDispTemp.concat(" m"))
dc.setDisplayListTemplate(FlowDispTemp)
dc.setDisplayListColor(VectColor) #Title's color is the vector color
dc.applyPreferences()
#OVERALL VIEW OF THE FINAL IMAGE
#=================================================================
#Get a ViewManager with a Navigation Display
VM = idv.getViewManager()
NavDis = VM.getNavigatedDisplay()
#Set vertical scale (important for isosurfaces, or when layering 2D plots),
#turn the bounding box on, and set the desired viewing angle.
NavDis.setVerticalRange(-0.1,0) #(Bottom, Top) in meters
NavDis.setBoxVisible(1)
NavDis.rotateView(vwinfo[0],vwinfo[1]) #(Azimuth, Tilt) in degrees
#Get the DisplayMaster to zoom in/out of the overall view by changing
#the scaling factor (1.0 by default). Addition of this parameter to
#the web interface should be useful too. NOTE: For some reason,
#VM.getAspectRatio() returns NULL, which is very strange for a display!
DM = VM.getMaster()
DM.zoom(vwinfo[2])
VM.setMasterActive()
#Write output file
if OneOrMoreTimesChoice == 0:
writeImage("hzt.png")
elif OneOrMoreTimesChoice == 1:
writeMovie("hzt.gif")
#END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment