Skip to content

Commit

Permalink
Scaling of colorscale. Setting colorscale to apply to selected view. …
Browse files Browse the repository at this point in the history
…Toggle views on and off.
  • Loading branch information
upibhalla committed Mar 13, 2022
1 parent b41d7d7 commit abc7c13
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 39 deletions.
108 changes: 75 additions & 33 deletions python/rdesigneur/moogul.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class MooView:
rgb = []
viewList = []
consolidatedTitle = ""
colorbarViewIdx = 0 # Which View does the colorbar serve?

def __init__( self, swx = 10, swy = 10, hideAxis = True, title = "view", colormap = 'jet'
):
Expand All @@ -58,6 +59,7 @@ def __init__( self, swx = 10, swy = 10, hideAxis = True, title = "view", colorma
self.valMmax = 1.0
self.simTime = 0.0
self.plotFlag_ = True
self.cbox = []

@staticmethod
def replayLoop():
Expand Down Expand Up @@ -121,60 +123,71 @@ def updateAxis( self ):
self.axisLength.text = "{:.2f} <i>u</i>m".format( dx * 1e6*self.scene.range * self.colorbar.width / self.scene.width )

def raiseMax( self, isDouble = False ):
valRange = self.valMax - self.valMin
moov = MooView.viewList[MooView.colorbarViewIdx]
valRange = moov.valMax - moov.valMin
if isDouble:
self.valMax = self.valMin + 2 * valRange
moov.valMax = moov.valMin + 2 * valRange
else:
self.valMax = self.valMin + valRange * 1.1111111111111111111111
moov.valMax = moov.valMin + valRange * 1.1111111111111111111111
return moov.valMax

def lowerMax( self, isDouble = False ):
valRange = self.valMax - self.valMin
moov = MooView.viewList[MooView.colorbarViewIdx]
valRange = moov.valMax - moov.valMin
if isDouble:
self.valMax = self.valMin + 0.5 * valRange
moov.valMax = moov.valMin + 0.5 * valRange
else:
self.valMax = self.valMin + valRange * 0.9
moov.valMax = moov.valMin + 0.9 * valRange
return moov.valMax

def raiseMin( self, isDouble = False ):
valRange = self.valMax - self.valMin
moov = MooView.viewList[MooView.colorbarViewIdx]
valRange = moov.valMax - moov.valMin
if isDouble:
self.valMin = self.valMmax - 0.5 * valRange
moov.valMin = moov.valMmax - 0.5 * valRange
else:
self.valMin = self.valMax - valRange * 0.9
moov.valMin = moov.valMax - valRange * 0.9
return moov.valMin

def lowerMin( self, isDouble = False ):
valRange = self.valMax - self.valMin
moov = MooView.viewList[MooView.colorbarViewIdx]
valRange = moov.valMax - moov.valMin
if isDouble:
self.valMin = self.valMax - 2 * valRange
moov.valMin = moov.valMax - 2 * valRange
else:
self.valMin = self.valMax - valRange * 1.1111111111111111111111


moov.valMin = moov.valMax - valRange * 1.1111111111111111111111
return moov.valMin

def scaleColorbar( self, event ):
loc = event.pos
#print( loc.y )
if loc.y > 6:
idx = MooView.colorbarViewIdx + 1
if idx >= len( MooView.viewList ):
idx = 0
self.selectCbar( idx )
return
if loc.y > 4 and loc.y < 4.7:
self.lowerMax( self.scene.mouse.shift )
self.barMax.text = "{:.3f}".format(self.valMax)
ret = self.lowerMax( self.scene.mouse.shift )
self.barMax.text = "{:.3e}".format(ret)
elif loc.y > 4.85 and loc.y < 5.5:
self.raiseMax( self.scene.mouse.shift )
self.barMax.text = "{:.3f}".format(self.valMax)
ret = self.raiseMax( self.scene.mouse.shift )
self.barMax.text = "{:.3e}".format(ret)
elif loc.y > -3.25 and loc.y < -2.6:
self.raiseMin( self.scene.mouse.shift )
self.barMin.text = "{:.3f}".format(self.valMin)
ret = self.raiseMin( self.scene.mouse.shift )
self.barMin.text = "{:.3e}".format(ret)
elif loc.y > -3.95 and loc.y < -3.45:
self.lowerMin( self.scene.mouse.shift )
self.barMin.text = "{:.3f}".format(self.valMin)
self.drawables_[0].updateLimits( self.valMin, self.valMax )
ret = self.lowerMin( self.scene.mouse.shift )
self.barMin.text = "{:.3e}".format(ret)
for moov in MooView.viewList:
moov.drawables_[0].updateLimits( moov.valMin, moov.valMax )

def innerColorbar( self, title, bg ):
barWidth = SCALE_SCENE * 1.5
if ( bgLookup(bg).mag < 1 ):
barTextColor = vp.color.white
else:
barTextColor = vp.color.black
self.colorbar = vp.canvas( title = title, width = barWidth, height = self.swy * SCALE_SCENE, background = bgLookup(bg), align = 'left', range = 1, autoscale = False )
#self.colorbar = vp.canvas( title = title, width = barWidth, height = self.swy * SCALE_SCENE, background = vp.color.cyan, align = 'left', range = 1, autoscale = False )
self.colorbar = vp.canvas( title = "Datasets = ", width = barWidth, height = self.swy * SCALE_SCENE, background = bgLookup(bg), align = 'left', range = 1, autoscale = False )
self.colorbar.userzoom = False
self.colorbar.userspin = False
self.colorbar.userpan = False
Expand All @@ -185,10 +198,11 @@ def innerColorbar( self, title, bg ):
axOrigin = vp.vector( 0, -5.5, 0 )
for idx, rgb in enumerate( self.rgb ):
cbox = vp.box( canvas = self.colorbar, pos = vp.vector( 0, height * (idx - 26), 0), width = width, height = height, color = rgb )
barName = self.title.replace( ' ', '\n' )
barName = self.title.replace( '.', '\n' )
barName = barName.replace( '/', '\n', 1 )
self.barName = vp.label( canvas = self.colorbar, align = 'left', pixel_pos = True, pos = vp.vector( 2, (self.swy - 0.32) * SCALE_SCENE, 0), text = barName, height = 15, color = barTextColor, box = False, opacity = 0 )
self.barMin = vp.label( canvas = self.colorbar, align = 'center', pixel_pos = True, pos = vp.vector( barWidth/2, self.swy * SCALE_SCENE * 0.22, 0), text = "{:.3f}".format(self.valMin), height = 12, color = barTextColor, box = False, opacity = 0 )
self.barMax = vp.label( canvas = self.colorbar, align = 'center', pixel_pos = True, pos = vp.vector( barWidth/2, (self.swy - 1.2) * SCALE_SCENE, 0), text = "{:.3f}".format(self.valMax), height = 12, color = barTextColor, box = False, opacity = 0 )
self.barMin = vp.label( canvas = self.colorbar, align = 'center', pixel_pos = True, pos = vp.vector( barWidth/2, self.swy * SCALE_SCENE * 0.22, 0), text = "{:.3e}".format(self.valMin), height = 12, color = barTextColor, box = False, opacity = 0 )
self.barMax = vp.label( canvas = self.colorbar, align = 'center', pixel_pos = True, pos = vp.vector( barWidth/2, (self.swy - 1.2) * SCALE_SCENE, 0), text = "{:.3e}".format(self.valMax), height = 12, color = barTextColor, box = False, opacity = 0 )
self.xAx = vp.cylinder( canvas = self.colorbar, pos = axOrigin, axis = vp.vector( 0.8, 0, 0 ), radius = 0.04, color = vp.color.red )
self.yAx = vp.cylinder( canvas = self.colorbar, pos = axOrigin, axis = vp.vector( 0, 0.8, 0 ), radius = 0.04, color = vp.color.green )
self.zAx = vp.cylinder( canvas = self.colorbar, pos = axOrigin, axis = vp.vector( 0, 0, 0 ), radius = 0.04, color = vp.color.blue )
Expand All @@ -200,12 +214,32 @@ def makeColorbar( self, doOrnaments = True, colorscale = 'jet', bg = 'default' )
title = MooView.consolidatedTitle + "\n"
self.innerColorbar( title, bg )
if doOrnaments:
for idx, mv in enumerate( MooView.viewList ):
chk = vp.checkbox( bind = mv.toggleView, checked = True, text = mv.title + " ", pos = self.colorbar.title_anchor )
chk.idx = idx
self.cbox.append( chk )
self.colorbar.append_to_title("\n")
self.timeLabel = vp.wtext( text = "Time = 0.000 sec", pos = self.colorbar.title_anchor )
self.sleepLabel = vp.wtext( text = " Frame dt = 0.005 sec", pos = self.colorbar.title_anchor )
self.sleepSlider = vp.slider( pos = self.colorbar.title_anchor, length = 200, bind = self.setSleepTime, min = 0, max = len( sleepTimes ) -1, value = min( len( sleepTimes ), 2 ) )
self.replayButton = vp.button( text = "Start Replay", pos = self.colorbar.title_anchor, bind=self.toggleReplay, disabled = True )
self.colorbar.append_to_title("\n")

def selectCbar( self, idx ):
MooView.colorbarViewIdx = idx
moov = MooView.viewList[idx]
view0 = MooView.viewList[0]
view0.barName.text = view0.cbox[idx].text.replace( '.', '\n' )
view0.barName.text = view0.barName.text.replace( '/', '\n', 1 )
view0.barMin.text = "{:.3e}".format(moov.valMin)
view0.barMax.text = "{:.3e}".format(moov.valMax)

def toggleView( self, cbox ):
for d in self.drawables_:
d.setVisible( cbox.checked )
if cbox.checked: # The colorbar is assigned to selected view:
self.selectCbar( cbox.idx )

def pickObj( self ):
obj = self.scene.mouse.pick
if obj == None:
Expand Down Expand Up @@ -285,7 +319,6 @@ def firstDraw( self, mergeDisplays, rotation=0.0, elev=0.0, azim=0.0, center = [
else:
self.doAutoscale()
self.updateAxis()
print( "Self.viewIDX = ", self.viewIdx, ", MOOView.viewIdx = ", MooView.viewIdx )
if self.viewIdx == (MooView.viewIdx-1):
MooView.viewList[0].graph = vp.graph( title = "Graph", xtitle = "Time (s)", ytitle = " Units here", width = 700, fast=False, align = "left" )
MooView.viewList[0].graphPlot1 = vp.gcurve( color = vp.color.blue, interval=-1)
Expand Down Expand Up @@ -480,6 +513,7 @@ def __init__( self,
self.valMax = valMax
self.segments = []
self.snapshot = []
self.visible = True
#cmap = plt.get_cmap( self.colormap, lut = NUM_CMAP )
#self.rgb = [ list2vec(cmap(i)[0:3]) for i in range( NUM_CMAP ) ]

Expand All @@ -500,7 +534,7 @@ def updateValues( self, simTime ):
indices = np.maximum( np.minimum( scaleVal, NUM_CMAP-0.5), 0.0).astype(int)

# Have to figure how this will work with multiple update rates.
self.snapshot.append( [simTime, indices] )
self.snapshot.append( [simTime, self.val] )

self.displayValues( indices )

Expand All @@ -512,7 +546,6 @@ def updateLimits( self, vmin, vmax ):
valMin = self.valMin = vmin
valMax = self.valMax = vmax
scaleVal = NUM_CMAP * (self.val - valMin) / (valMax - valMin)
#indices = scaleVal.ndarray.astype( int )
indices = np.maximum( np.minimum( scaleVal, NUM_CMAP-0.5), 0.0).astype(int)
self.displayValues( indices )

Expand All @@ -525,7 +558,9 @@ def displayValues( self, indices ):
def replaySnapshot( self, idx ):
if idx >= len( self.snapshot ):
return 0.0
self.displayValues( self.snapshot[idx][1] )
scaleVal = NUM_CMAP * (self.snapshot[idx][1] - self.valMin) / (self.valMax - self.valMin)
indices = np.maximum( np.minimum( scaleVal, NUM_CMAP-0.5), 0.0).astype(int)
self.displayValues( indices )
return self.snapshot[idx][0] # return frame time

def updateDiameter( self ):
Expand Down Expand Up @@ -559,6 +594,13 @@ def plotHistory( self, path, field, graph, plot ):
dat = [[x,y] for x, y in zip( t, v ) ]
plot.data = dat

def setVisible( self, state ):
if self.visible == state:
return
self.visible = state
for s in self.segments:
s.visible = state


#####################################################################

Expand Down
55 changes: 49 additions & 6 deletions python/rdesigneur/nsdfview.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import moogul
mooViews = []

defaultFieldRange = { 'conc': [0.0, 1.0], 'n': [0, 10], 'Vm': [-0.7, 0.02], 'Ik':[-1e-9, 1e-9], 'Ca':[0.0, 1.0] }

class ObjHandle:
def __init__( self, path ):
self.path = str( path, "utf-8" )
Expand Down Expand Up @@ -151,7 +153,7 @@ def getHistory( self, path, field ):
return t, val

#####################################################################
def listElecDatasets( nsdf ):
def printElecDatasetInfo( nsdf ):
elec = nsdf["/data/uniform/%elec"]
for ee in elec:
path = ""
Expand All @@ -169,11 +171,11 @@ def listElecDatasets( nsdf ):
shape = dataset.shape
print( "Elec: {:<36} shape=({}), dt={}".format( path, shape, dt ) )

def listDatasets( nsdf ):
def printDatasetInfo( nsdf ):
uniform = nsdf["/data/uniform"]
for uu in uniform:
if uu == "%elec":
listElecDatasets( nsdf )
printElecDatasetInfo( nsdf )
else:
group = uniform[uu]
path = uu[1:]
Expand All @@ -186,6 +188,33 @@ def listDatasets( nsdf ):
shape = dataset.shape
print( "Chem: {:<36} shape=({}), dt={}".format( path + '.' + datasetName, shape, dt ) )

def listDatasets( nsdf ):
## Returns list of datasets in path.field format.
ret = []
uniform = nsdf["/data/uniform"]
for uu in uniform:
if uu == "%elec":
elec = nsdf["/data/uniform/%elec"]
for ee in elec:
path = ""
spl = ee.split( '%', 1 )
if spl[0] == "##[ISA=CompartmentBase]":
path += "#"
else:
path = spl[0]
if len( spl ) > 1:
path += '/' + spl[1].replace( '%', '/' )
for field in elec[ee]:
ret.append( path + '.' + field )
else:
group = uniform[uu]
for ch in group:
path = uu[1:] + '/' + ch.replace( '%', '/' )
if path[-2:] == '[]':
path = path[:-2]
for field in group[ch]:
ret.append( path + '.' + field )
return ret

#####################################################################
def main():
Expand All @@ -199,23 +228,37 @@ def main():
parser.add_argument( '-l', '--list_datasets', action="store_true", help="List possible datasets available to view." )
args = parser.parse_args()

'''
if (not args.list_datasets) and len( args.viewspec ) == 0:
print( "warning: No viewpsec defined in command line" )
quit()
'''

nsdf = h5py.File( args.NSDF_filename, 'r' )
if args.list_datasets:
listDatasets( nsdf )
printDatasetInfo( nsdf )
quit()

if len( args.viewspec ) == 0:
viewspec = []
datasets = listDatasets( nsdf )
for ds in datasets:
spl = ds.split( '.' )
dispMin, dispMax = defaultFieldRange[ spl[1] ]
viewspec.append( [spl[0], spl[1], dispMin, dispMax ] )
merge_displays = True
else:
viewspec = args.viewspec
merge_displays = args.merge_displays

viewer = []
for vs in args.viewspec:
for vs in viewspec:
viewer.append( makeMoogli( nsdf, vs ) )
dt = viewer[0].drawables_[0].dataWrapper_.dt_
shape = viewer[0].drawables_[0].dataWrapper_.getShape()
numSteps = shape[1]
for v in viewer:
v.firstDraw( args.merge_displays, rotation = args.rotation, colormap = args.colormap, bg = args.background )
v.firstDraw( merge_displays, rotation = args.rotation, colormap = args.colormap, bg = args.background )

simTime = 0.0
for step in range( numSteps ):
Expand Down

0 comments on commit abc7c13

Please sign in to comment.