Commit d14d18f7 authored by cyrush's avatar cyrush
Browse files

visit_utils: add moab and slurm helpers, add qplot Qt based offscreen plotting module

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@27836 18c085ea-50e0-402c-830e-de6fd14e8384
parent 3e87f80f
......@@ -69,9 +69,9 @@ setup(name='visit_utils',
version='0.1',
author = 'Cyrus Harrison',
author_email = 'cyrush@llnl.gov',
description='VisIt Utilties Module',
description='VisIt Utilities Module',
package_dir = {'visit_utils':'src'},
packages=['visit_utils','visit_utils.qannote'],
packages=['visit_utils','visit_utils.qannote','visit_utils.qplot'],
cmdclass = { 'test': setup_tests.ExecuteTests})
if using_visit:
......
......@@ -49,7 +49,11 @@ import encoding
import status
import ult
import moab
import slurm
import qannote
import qplot
from query import query, python_query
from windows import Window, WindowManager
......
#!/usr/bin/env python
#*****************************************************************************
#
# Copyright (c) 2000 - 2015, Lawrence Livermore National Security, LLC
# Produced at the Lawrence Livermore National Laboratory
# LLNL-CODE-442911
# All rights reserved.
#
# This file is part of VisIt. For details, see https://visit.llnl.gov/. The
# full copyright notice is contained in the file COPYRIGHT located at the root
# of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the disclaimer below.
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the disclaimer (as noted below) in the
# documentation and/or other materials provided with the distribution.
# - Neither the name of the LLNS/LLNL nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
# LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#*****************************************************************************
#*****************************************************************************
"""
file: moab.py
description:
Provides a python command for msub submission.
"""
import os
from visit_utils.common import *
class MsubError(Exception):
def __init__(self,emsg):
self.msg = "<msub error:> " + emsg
def msub(cmd,rmin,nnodes=1,mach=None,part="pbatch",bank="bdivp",rdir=None,obase=None,depend=None):
if mach is None:
mach = hostname(False)
# create output file name
if obase is None:
ctoks = cmd.split()
sname = os.path.split(ctoks[0])[1]
obase = sname
ofile = "out.moab.%s.%s.%s.txt" % (obase,hostname(),timestamp())
xcmd = "msub -o %s -l nodes=%d -l walltime=%s:00 " % (ofile,nnodes, str(rmin))
if not rdir is None:
xcmd += " -d %s " % (os.path.abspath(rdir))
if not depend is None:
xcmd += "-l depend=%s " % depend
xcmd += "-q %s -A %s %s" % (part,bank,cmd)
ret,out = sexe(xcmd,ret_output=True,echo=True)
if ret == 0:
jid = int(out.split(" ")[-1].strip())
return jid, ofile
else:
raise MsubError(out)
\ No newline at end of file
......@@ -73,6 +73,31 @@ def process_encoded_text(val):
res += val[prev:]
return res
class Annotations(object):
@classmethod
def create(cls,params):
itype = params.type.lower()
if itype == "text":
return Text(params)
elif itype == "image":
return Image(params)
elif itype == "line":
return Line(params)
elif itype == "arrow":
return Arrow(params)
elif itype == "rect":
return Rect(params)
elif itype == "circle":
return Circle(params)
elif itype == "ellipse":
return Ellipse(params)
elif itype == "textbox":
return TextBox(params)
elif itype == "multiprogressbar":
return MultiProgressBar(params)
else:
return None
class CanvasItem(object):
def __init__(self,params,defaults=None):
......
#*****************************************************************************
#
# Copyright (c) 2000 - 2015, Lawrence Livermore National Security, LLC
# Produced at the Lawrence Livermore National Laboratory
# LLNL-CODE-442911
# All rights reserved.
#
# This file is part of VisIt. For details, see https://visit.llnl.gov/. The
# full copyright notice is contained in the file COPYRIGHT located at the root
# of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the disclaimer below.
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the disclaimer (as noted below) in the
# documentation and/or other materials provided with the distribution.
# - Neither the name of the LLNS/LLNL nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
# LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#*****************************************************************************
"""
file: __init__.py
author: Cyrus Harrison <cyrush@llnl.gov>
description:
Init file for 'visit_utils.qplot' module.
qplot is Qt based offscreen Curve Rendering lib.
"""
from scene import *
from plots import *
#*****************************************************************************
#
# Copyright (c) 2000 - 2015, Lawrence Livermore National Security, LLC
# Produced at the Lawrence Livermore National Laboratory
# LLNL-CODE-442911
# All rights reserved.
#
# This file is part of VisIt. For details, see https://visit.llnl.gov/. The
# full copyright notice is contained in the file COPYRIGHT located at the root
# of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the disclaimer below.
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the disclaimer (as noted below) in the
# documentation and/or other materials provided with the distribution.
# - Neither the name of the LLNS/LLNL nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
# LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#*****************************************************************************
"""
file: qplot/plots.py
author: Cyrus Harrison <cyrush@llnl.gov>
description:
Qt based offscreen Curve Rendering lib.
"""
import sys
import time
import math
from visit_utils.property_tree import PropertyTree
from visit_utils import ult
from visit_utils.qannote import *
def log10(val):
if val != 0.0:
return math.log10(val)
else:
return 0.0
def lerp(s0,s1,xval,log_scale_y=False):
x0,y0 = s0.x, s0.y
x1,y1 = s1.x, s1.y
if log_scale_y:
y0 = log10(y0)
y1 = log10(y1)
res = (y1-y0) * (xval - x0) / (x1 - x0) + y0
return xval,res
class Plots(object):
@classmethod
def create(cls,scene,params):
itype = params.type.lower()
cfname = params.curve.file
cidx = params.curve.index
curves =ult.Curve.load(cfname)
curve = curves[cidx]
if itype == "line":
return LinePlot(curve,scene,params)
elif itype == "area":
return AreaPlot(curve,scene,params)
elif itype == "tracer_dot":
return TracerDotPlot(curve,scene,params)
elif itype == "tracer_line":
return TracerLinePlot(curve,scene,params)
return None
class CurvePlot(CanvasItem):
def __init__(self,curve,scene,params,defaults=None):
self.curve = curve
self.scene = scene
defs = PropertyTree()
defs.log_scale_y = False
defs.color = (255,255,255,255)
if not defaults is None:
defs.update(defaults)
CanvasItem.__init__(self,params,defs)
class IntervalPlot(CurvePlot):
def __init__(self,curve,scene,params,defaults=None):
CurvePlot.__init__(self,curve,scene,params,defaults)
nsamps = len(curve)
self.start_x = self.curve.samples[0].x
self.start_index = 0
self.stop_x = self.curve.samples[-1].x
self.stop_index = len(self.curve.samples) -1
if self.params.has_property("start_x"):
xval = self.params.start_x
idx = curve.find_index(xval)
if not idx is None:
self.start_index = idx
self.start_x = xval
elif self.params.has_property("start_index"):
idx = self.params.start_index
s = curve.get_sample(idx)
if not s is None:
self.start_index = idx
self.start_x = s.x
if self.params.has_property("stop_x"):
xval = self.params.stop_x
idx = curve.find_index(xval)
if not idx is None:
self.stop_index = idx
self.stop_x = xval
elif self.params.has_property("stop_index"):
idx = self.params.stop_index
s = curve.get_sample(idx)
if not s is None:
self.stop_index = idx
self.stop_x = s.x
def interval_data(self):
res = []
nsamps = len(self.curve.samples)
start = self.start_index
stop = self.stop_index
start_x = self.start_x
stop_x = self.stop_x
if self.curve.samples[start].x != start_x:
# interp ...
s0 = self.curve.samples[start]
s1 = self.curve.samples[start+1]
cx = start_x
cx,cy = lerp(s0,s1,start_x,self.params.log_scale_y)
res.append(ult.Sample(cx,cy))
for i in xrange(start,stop+1):
s = self.curve.samples[i]
cx,cy = s.x, s.y
if self.params.log_scale_y:
cy = log10(cy)
res.append(ult.Sample(cx,cy))
# see if we need to lerp to hit final value
if stop < nsamps-1 and self.curve.samples[stop].x != stop_x:
s0 = self.curve.samples[stop]
s1 = self.curve.samples[stop+1]
cx,cy = lerp(s0,s1,stop_x,self.params.log_scale_y)
res.append(ult.Sample(cx,cy))
return res
class LinePlot(IntervalPlot):
def __init__(self,curve,scene,params):
defs = PropertyTree()
defs.line_width = 3
IntervalPlot.__init__(self,curve,scene,params,defs)
def render(self,painter):
self.scene.set_curve_viewport(painter)
isamples = self.interval_data()
nsamps = len(isamples)
painter.setBrush(Qt.NoBrush)
c = self.params.color
color = QColor(c[0],c[1],c[2],c[3])
line_width = self.params.line_width
pen = QPen(color,line_width,Qt.SolidLine,Qt.RoundCap,Qt.RoundJoin)
pen.setCosmetic(True)
painter.setPen(pen)
path = QPainterPath()
path.moveTo(isamples[0].x,isamples[0].y)
for i in xrange(1,nsamps):
path.lineTo(isamples[i].x,isamples[i].y)
painter.drawPath(path)
class AreaPlot(IntervalPlot):
def __init__(self,curve,scene,params):
defs = PropertyTree()
defs.line_width = 3
IntervalPlot.__init__(self,curve,scene,params,defs)
def render(self,painter):
self.scene.set_curve_viewport(painter)
isamples = self.interval_data()
nsamps = len(isamples)
painter.setBrush(Qt.NoBrush)
c = self.params.color
color = QColor(c[0],c[1],c[2],c[3])
line_width = self.params.line_width
pen_color = QColor(c[0],c[1],c[2],c[3])
pen_color.setAlpha(255)
pen = QPen(color,line_width,Qt.SolidLine)
pen.setCosmetic(True)
painter.setPen(pen)
painter.setBrush(QBrush(color))
extents = self.curve.extents()
xmin = isamples[0].x
ymin = extents[2]
if self.params.log_scale_y:
ymin = log10(ymin)
path = QPainterPath()
path.moveTo(xmin,ymin)
for i in xrange(0,nsamps):
path.lineTo(isamples[i].x,isamples[i].y)
# complete the circit
path.lineTo(isamples[-1].x,ymin)
path.lineTo(xmin,ymin)
painter.drawPath(path)
class TracerDotPlot(CurvePlot):
def __init__(self,curve,scene,params):
defs = PropertyTree()
defs.point_size = 15
CurvePlot.__init__(self,curve,scene,params,defs)
self.tracer_x = 0.0
self.tracer_y = 0.0
self.tracer_index = None
if self.params.has_property("tracer_x"):
xval = self.params.tracer_x
idx = curve.find_index(xval)
if not idx is None:
self.tracer_index = idx
if xval == curve.samples[idx].x:
self.tracer_x = xval
self.tracer_y = curve.samples[idx].y
else:
s0 = curve.samples[idx]
s1 = curve.samples[idx+1]
self.tracer_x,self.tracer_y = lerp(s0,s1,xval,self.params.log_scale_y)
elif self.params.has_property("tracer_index"):
idx = self.params.tracer_index
xval = curve.find_xvalue(idx)
if not xval is None:
self.tracer_index = idx
self.tracer_x = xval
self.tracer_y = curve.samples[idx].y
if self.parmas.log_scale_y:
self.tracer_y = log10(self.tracer_y)
def render(self,painter):
self.scene.set_curve_viewport(painter)
nsamps = len(self.curve.samples)
if self.tracer_index is None or self.tracer_index > nsamps:
return
painter.setBrush(Qt.NoBrush)
c = self.params.color
color = QColor(c[0],c[1],c[2],c[3])
pen = QPen(color,self.params.point_size,Qt.SolidLine,Qt.RoundCap,Qt.RoundJoin)
pen.setCosmetic(True)
painter.setPen(pen)
tx,ty = self.tracer_x, self.tracer_y
painter.drawPoint(QPointF(tx,ty))
class TracerLinePlot(CurvePlot):
def __init__(self,curve,scene,params):
defs = PropertyTree()
defs.tracer_orientation = 1
CurvePlot.__init__(self,curve,scene,params,defs)
self.tracer_x = 0.0
self.tracer_y = 0.0
self.tracer_index = None
if self.params.has_property("tracer_x"):
xval = self.params.tracer_x
idx = curve.find_index(xval)
if not idx is None:
if xval == curve.samples[idx].x:
self.tracer_x = xval
self.tracer_y = curve.samples[idx].y
else:
s0 = curve.samples[idx]
s1 = curve.samples[idx+1]
self.tracer_x,self.tracer_y = lerp(s0,s1,xval,self.params.log_scale_y)
elif self.params.has_property("tracer_index"):
idx = self.params.tracer_index
xval = curve.find_xvalue(idx)
if not xval is None:
self.tracer_index = idx
self.tracer_x = xval
self.tracer_y = curve.samples[idx].y
if self.parmas.log_scale_y:
self.tracer_y = log10(self.tracer_y)
def render(self,painter):
self.scene.set_curve_viewport(painter)
painter.setBrush(Qt.NoBrush)
c = self.params.color
color = QColor(c[0],c[1],c[2],c[3])
pen = QPen(color,2,Qt.DashLine)
pen.setCosmetic(True)
painter.setPen(pen)
painter.setBrush(QBrush(color))
extents = self.curve.extents()
xmin,xmax, ymin ,ymax = self.scene.params.view
py = self.tracer_y
if self.params.log_scale_y:
ymin = log10(ymin)
ymax = log10(ymax)
path = QPainterPath()
if self.params.tracer_orientation == 1:
path.moveTo(self.tracer_x,ymin)
path.lineTo(self.tracer_x,ymax)
else:
path.moveTo(xmin,py)
path.lineTo(xmax,py)
painter.drawPath(path)
\ No newline at end of file
#*****************************************************************************
#
# Copyright (c) 2000 - 2015, Lawrence Livermore National Security, LLC
# Produced at the Lawrence Livermore National Laboratory
# LLNL-CODE-442911
# All rights reserved.
#
# This file is part of VisIt. For details, see https://visit.llnl.gov/. The
# full copyright notice is contained in the file COPYRIGHT located at the root
# of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# - Redistributions of source code must retain the above copyright notice,
# this list of conditions and the disclaimer below.
# - Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the disclaimer (as noted below) in the
# documentation and/or other materials provided with the distribution.
# - Neither the name of the LLNS/LLNL nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE LIVERMORE NATIONAL SECURITY,
# LLC, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#*****************************************************************************
"""
file: qplot/scene.py
author: Cyrus Harrison <cyrush@llnl.gov>
description:
Qt based offscreen Curve Rendering lib.
"""
import sys
import time
import math
from visit_utils.property_tree import PropertyTree
from visit_utils import ult
from visit_utils.property_tree import PropertyTree
from visit_utils import ult
from visit_utils.qannote import *
from plots import *
class PlotGrid(object):
def __init__(self,params,scene):
self.scene = scene
self.params = PropertyTree(init={"line_width":0,
"x_bins":10,
"y_bins":10})
self.params.update(params)
def render(self,painter):
self.scene.set_scene_viewport(painter)
fg = self.scene.params.fg_color
x_bins = self.params.x_bins
y_bins = self.params.y_bins
pen = QPen(QColor(fg[0],fg[1],fg[2],fg[3]),
self.params.line_width,
Qt.SolidLine,Qt.SquareCap,Qt.MiterJoin)
pen.setCosmetic(True)
painter.setPen(pen)
painter.setBrush(Qt.NoBrush)
dx = 100.0 / (x_bins-1)
dy = 100.0 / (y_bins-1)
cx,cy = 0.0,0.0
for i in xrange(x_bins):
painter.drawLine(QPointF(cx,0.0),QPointF(cx,100.0))
cx+=dx
for i in xrange(y_bins):
painter.drawLine(QPointF(0.0,cy),QPointF(100.0,cy))
cy+=dy
class PlotAxes(object):
def __init__(self,params,scene):
self.scene = scene
self.params = PropertyTree(init={"line_width":2,
"full_box":True,
"x_ticks":5,
"y_ticks":5,
"tick_length":1.0,
"tick_width":2.0,
"show_ticks":True})
self.params.update(params)
def render(self,painter):
self.scene.set_scene_viewport(painter)
fg = self.scene.params.fg_color
x_ticks = self.params.x_ticks
y_ticks = self.params.y_ticks
tick_width = self.params.tick_width
tick_len = self.params.tick_length
fgcolor = QColor(fg[0],fg[1],fg[2],fg[3])
pen = QPen(fgcolor,
self.params.line_width,