from __future__ import print_function
import os, io, time, math
from errno import ENOENT
import pandas as pd
import numpy as np
#import tifffile
import scipy.misc
#from pymapmanager.version import __version__
from pymapmanager.mmUtil import newplotdict
from pymapmanager.mmStack import mmStack
from pymapmanager.mmio import mmio
'''3D numpy array, rows are stack centric indices, columns are sessions, 3rd dimension is:
[0] idx, [1] next, [2] nextTP, [3] prev, [4] prevTP
[5] blank, [6] runIdx, [7] dynType, [8] forced
[9] nodeType, [10] segmentID, [11] splitIdx
'''
[docs]class mmMap():
"""
A time-series of :class:`pymapmanager.mmStack` time-points plus some book-keeping to link corresponding annotations
and segments between time-points.
Args:
filePath (str): Full file path to .txt file for the map. File is inside map folder, for map a5n it is /a5n/a5n.txt
urlmap (str): Name of the map to load from a :class:`pymapmanager.mmio` online repository.
Example::
from pymapmanager.mmMap import mmMap
myMapFile = 'PyMapManager/examples/exampleMaps/rr30a/rr30a.txt'
myMap = mmMap(filePath=myMapFile)
# Get the 3rd mmStack using
stack = myMap.stacks[3]
# Retrieve annotations (for a given segmentID) across all time-points in the map
pDist_values = myMap.getMapValues2('pDist', segmentID=[3])
"""
def __init__(self, filePath=None, urlmap=None):
startTime = time.time()
self.filePath = ''
# Full file path to .txt file for the map.
self._folder = ''
# Path to enclosing folder, ends in '/'.
self.name = ''
# Name of the map. For a map loaded with file a5n.txt, name is a5b. Same as enclosing folder name.
# If urlmap then this is the name of the map to fetch from a :class:`pymapmanager.mmio` server.
self.table = None
# Pandas dataframe loaded from .txt file filePath or 'header' if using :class:`pymapmanager.mmio`.
# Get values from this dataframe using getValue(name,sessionNumber)
# removed 20170107, replaced with xxx
# self.defaultRoiType = 'spineROI'
#self.defaultRoiTypeID = 0
self.server = None
# Pointer to :class:`pymapmanager.mmio` server connection.
# Only used to load from urlmap.
self.objMap = None
# 2D array where each row is a run of annotations.
# objMap[i][j] gives us a mmStack centric index into mmStack.stackdb.
self.segMap = None
# 2D array where each row is a run of segments.
# segMap[i][j] gives us mmStack centric index into mmStack._line
self.segRunMap = None # 20180107, why was this not defaulted?
###############################################################################
# map nv
doFile = True
if filePath is not None:
if not os.path.isfile(filePath):
raise IOError(ENOENT, 'mmMap did not find filePath:', filePath)
self.filePath = filePath # Path to file used to open map."""
self._folder = os.path.dirname(filePath) + '/'
self.name = os.path.basename(filePath).strip('.txt')
self.table = pd.read_table(filePath, index_col=0)
elif urlmap is not None:
doFile = False
# try loading from url
self.name = urlmap
self.server = mmio.mmio()
tmp = self.server.getfile('header', self.name)
self.table = pd.read_table(io.StringIO(tmp.decode('utf-8')), index_col=0)
###############################################################################
# objMap (3d)
if doFile:
objMapFile = self._folder + self.name + '_objMap.txt'
if not os.path.isfile(objMapFile):
raise IOError(ENOENT, 'mmMap did not find objMapFile:', objMapFile)
with open(objMapFile, 'rU') as f:
header = f.readline().rstrip()
self.objMap = np.loadtxt(objMapFile, skiprows=1)
else:
tmp = self.server.getfile('objmap', self.name)
header = tmp.split('\n')[0]
self.objMap = np.loadtxt(tmp.split('\n'), skiprows=1)
if header.endswith(';'):
header = header[:-1]
header = header.split(';')
d = dict(s.split('=') for s in header)
numRow = int(d['rows'])
numCol = int(d['cols'])
numBlock = int(d['blocks'])
self.objMap.resize(numBlock,numRow,numCol)
self.runMap = self._buildRunMap(self.objMap, roiTypeID=self.defaultAnnotationID)
###############################################################################
# segMap (3d)
header = None
if doFile:
segMapFile = self._folder + self.name + '_segMap.txt'
if os.path.isfile(segMapFile):
with open(segMapFile, 'rU') as f:
header = f.readline().rstrip()
self.segMap = np.loadtxt(segMapFile, skiprows=1)
else:
#raise IOError(ENOENT, 'mmMap did not find segMapFile:', segMapFile)
print('did not find segment map file, should be ok')
else:
tmp = self.server.getfile('segmap', self.name)
#header = tmp.split('\r')[0] # works when server is running on OSX
header = tmp.split('\n')[0]
self.segMap = np.loadtxt(tmp.split('\n'), skiprows=1)
if header is not None:
if header.endswith(';'):
header = header[:-1]
header = header.split(';')
d = dict(s.split('=') for s in header)
numRow = int(d['rows'])
numCol = int(d['cols'])
numBlock = int(d['blocks'])
self.segMap.resize(numBlock,numRow,numCol)
self.segRunMap = self._buildRunMap(self.segMap, roiTypeID = None)
###############################################################################
#load each stack db
# this assumes self.objMap has already been loaded
self._stacks = [] # A list of mmStack
for i in range(0, self.numSessions):
if doFile:
stack = mmStack(name=self._getStackName(i), numChannels=self.numChannels, \
map=self, mapSession=i)
else:
stack = mmStack(name=self._getStackName(i), numChannels=self.numChannels, \
map=self, mapSession=i, urlmap=self.name)
self.stacks.append(stack)
stopTime = time.time()
print('map', self.name, 'loaded in', round(stopTime-startTime,2), 'seconds.')
@property
def numChannels(self):
"""
Number of image channels in each stack (must be the same for all stacks).
"""
return int(self.getValue('numChannels', 0))
@property
def numSessions(self):
"""
Number of sessions (timepoints) in the map (time-series).
"""
return int(self.table.loc['hsStack'].count())
@property
def stacks(self):
"""
List of :class:`pymapmanager.mmStack` in the map.
"""
return self._stacks
@property
def numMapSegments(self):
"""The number of line segments in the map.
Corresponding segments are connected together with the segMap.
"""
if self.segMap is not None:
numSegments = self.segRunMap.shape[0]
else:
numSegments = 0
return numSegments
@property
def defaultAnnotation(self):
"""
"""
# if defaultAnnotation does not exist then default to 'spineROI'
if 'defaultAnnotation' in self.table.index:
theRet = self.table.loc['defaultAnnotation'][0]
# if empty then we assume 'spineROI'
if theRet == '':
theRet = 'spineROI'
else:
theRet = 'spineROI'
return theRet
@property
def defaultAnnotationID(self):
theRet = 0
defaultAnnotation = self.defaultAnnotation
if defaultAnnotation == 'spineROI':
theRet = 0
elif defaultAnnotation == 'otherROI':
theRet = 4
return theRet
def __str__(self):
objCount = 0
for stack in self.stacks:
objCount += stack.numObj
'''
theRet = {}
theRet['info'] = ('map:' + self.name
+ ' map segments:' + str(self.numMapSegments)
+ ' stacks:' + str(self.numSessions)
+ ' total object:' + str(objCount))
theRet['map'] = self
'''
retStr = ('map:' + self.name
+ ' map segments:' + str(self.numMapSegments)
+ ' stacks:' + str(self.numSessions)
+ ' total object:' + str(objCount))
return retStr
def __iter__(self):
i = 0
while i < len(self.stacks):
yield self.stacks[i]
i += 1
[docs] def mapInfo(self):
"""
Get information on the map
Returns:
| A dict of
| mapName : Str
| numSessions : Int
| numChannels : Int
| numMapSegments : Int
|
| The following are string list with numSessions elements
| stackNames :
| importedStackName :
| numSlices :
| date :
| time :
| dx : Voxel size in um
| dy : Voxel size in um
| dz : Voxel size in um
| px : Number of Pixels
| py : Number of Pixels
| pz : Number of Pixels
| ...
"""
theRet = {}
theRet['mapName'] = self.name
theRet['numSessions'] = self.numSessions
theRet['numChannels'] = self.numChannels
theRet['defaultAnnotation'] = self.defaultAnnotation
theRet['numAnnotations'] = 0
# lists, one value per session
theRet['stackNames'] = []
theRet['importedStackName'] = []
theRet['date'] = []
theRet['time'] = []
theRet['px'] = [] # pixels
theRet['py'] = []
theRet['numSlices'] = []
theRet['dx'] = [] # voxels in um
theRet['dy'] = []
theRet['dz'] = []
theRet['numROI'] = []
for idx in range(self.numSessions):
theRet['stackNames'].append(self.table.loc['hsStack'][idx])
theRet['importedStackName'].append(self.table.loc['importedStackName'][idx])
theRet['date'].append(self.table.loc['date'][idx])
theRet['time'].append(self.table.loc['time'][idx])
theRet['px'].append(self.table.loc['px'][idx])
theRet['py'].append(self.table.loc['py'][idx])
theRet['numSlices'].append(self.table.loc['pz'][idx]) # changing name
theRet['dx'].append(self.table.loc['dx'][idx])
theRet['dy'].append(self.table.loc['dy'][idx])
theRet['dz'].append(self.table.loc['dz'][idx])
thisNum = self.stacks[idx].countObj(roiType=self.defaultAnnotation)
theRet['numROI'].append(thisNum)
theRet['numAnnotations'] = theRet['numAnnotations'] + self.stacks[idx].numObj
runIdx = 6
if self.segMap is not None:
theRet['numMapSegments'] = self.segRunMap.shape[0]
else:
theRet['numMapSegments'] = 0
'''
# these were not being used
theRet['objMap'] = self.objMap[runIdx].astype('int') # from spine index to run index
theRet['runMap'] = self.runMap.astype('int') # from run idx to spine idx
theRet['segMap'] = None
theRet['numMapSegments'] = 0
if self.segMap is not None:
theRet['segMap'] = self.segMap.astype('int')
theRet['numMapSegments'] = self.segRunMap.shape[0]
'''
#print 'mapInfo() theRet:', theRet
return theRet
[docs] def getValue(self, name, sessionNumber):
"""
Get a value from the map (not from a stack!).
Args:
name: Name of map value
sessionNumber: Session number of the stack
Returns:
Str (this is a single value)
Examples::
m.getValue('pixelsz', 2) # get the number of z-slices (pixels) of stack 2.
m.getValue('voxelx', 5) # get the x voxel size of stack 5 (in um/pixel).
m.getValue('hsStack',3) # get the name of stack 3.
"""
return self.table.loc[name].iloc[sessionNumber] # .loc specifies row, .iloc specifies a column
def _getStackName(self, sessIdx):
# get the name of the stack at session sessIdx, this is contained in the map header
ret = self.getValue('hsStack', sessIdx)
if ret.endswith('_ch1'):
ret = ret[:-4]
return ret
[docs] def getMapDynamics(self, pd, thisMatrix=None):
if thisMatrix is None:
pd = self.getMapValues3(pd)
thisMatrix = pd['stackidx']
m = thisMatrix.shape[0]
n = thisMatrix.shape[1]
pd['dynamics'] = np.empty([m,n])
pd['dynamics'][:] = np.NAN
# 1:add, 2:sub, 3:transient, 4:persisten
kAdd = 1
kSubtract = 2
kTransient = 3
kPersistent = 4
for i in range(m):
for j in range(n):
if not thisMatrix[i,j]>=0:
continue
if j==0:
if thisMatrix[i,j+1]>=0:
pd['dynamics'][i,j] = kPersistent
else:
pd['dynamics'][i,j] = kSubtract
elif j==n-1:
if thisMatrix[i,j-1]>=0:
pd['dynamics'][i,j] = kPersistent
else:
pd['dynamics'][i,j] = kAdd
else:
added = not thisMatrix[i,j-1]>=0
subtracted = not thisMatrix[i,j+1]>=0
if added and subtracted:
pd['dynamics'][i,j] = kTransient
elif added:
pd['dynamics'][i,j] = kAdd
elif subtracted:
pd['dynamics'][i,j] = kSubtract
else:
pd['dynamics'][i,j] = kPersistent
return pd
[docs] def ingest(self, tp, channel=1):
"""
Take a raw 3D .tif and populate raw/ingest/tp<tp> with single channel .tif files.
Args:
tp (int) : The timepoint to ingest
channel (int) : The channel to ingest, valid channels are (1,2,3)
Returns:
None
"""
print('mmMap.ingest() is ingesting tp:', tp, 'channel:', channel)
outFileType = '.png'
# '/Users/cudmore/Desktop/tmp/'
savePath = self._folder # ends in '/'
savePath += 'raw/'
if not os.path.isdir(savePath):
os.makedirs(savePath)
savePath += 'ingested/'
if not os.path.isdir(savePath):
os.makedirs(savePath)
savePath += 'tp' + str(tp) + '/'
if not os.path.isdir(savePath):
os.makedirs(savePath)
maxSavePath = self._folder + 'raw/ingested/'
print(' loading full 3d .tif')
# load the full 3D .tif
image = self.stacks[tp].loadStackImages(channel=channel)
print(' image shape:', image.shape)
[slices, m, n] = image.shape
for slice in range(slices):
outfile = self.name + '_tp' + str(tp) + '_ch' + str(channel) + '_s' + str(slice).zfill(4) + outFileType
outfilepath = savePath + outfile
if slice % 10 == 0:
print(' saving slice:', slice, 'of', slices, outfilepath)
# this saves .png as 8-bit, I am not sure if it is doing normalization?
scipy.misc.imsave(outfilepath, image[slice,:,:])
# make maximal intensity projection
maxfile = 'MAX_' + self.name + '_tp' + str(tp) + '_ch' + str(channel) + outFileType
maxfilepath = maxSavePath + maxfile
print(' making and saving max project', maxfilepath)
max_ = np.zeros((m, n), dtype='uint8')
for slice in range(slices):
max_ = np.maximum(max_, image[slice,:,:])
# MAX_rr30a_tp0_ch2
scipy.misc.imsave(maxfilepath, max_)
print('done ingesting')
[docs] def getMapValues3(self, pd):
"""
Get values of a stack annotation across all stacks in the map.
Args:
pd (dict): A plot dictionary describing what to plot. Get default from mmUtil.newplotdict().
Returns:
| pd['x'], 2D ndarray of xstat values, rows are runs, cols are sessions, nan is where there is no stackdb annotation
| pd['y'], same
| pd['z'], same
| pd['stackidx'], Each [i]j[] gives the stack centric index of annotation value at [i][j].
| pd['mapsess'], Each [i][j] gives the map session of value at annotation [i][j].
| pd['runrow'],
"""
startTime = time.time()
# make sure pd['roitype'] is a list
if not isinstance(pd['roitype'], list):
pd['roitype'] = [pd['roitype']]
m = self.runMap.shape[0]
n = self.runMap.shape[1]
if pd['xstat']:
pd['x'] = np.empty([m, n])
pd['x'][:] = np.NAN
if pd['ystat']:
pd['y'] = np.empty([m, n])
pd['y'][:] = np.NAN
if pd['zstat']:
pd['z'] = np.empty([m, n])
pd['z'][:] = np.NAN
# keep track of stack centric index we are plotting
yIdx = np.empty([m, n])
yIdx[:] = np.NAN
# keep track of session index
ySess = np.empty([m, n])
ySess[:] = np.NAN
# keep track of run map rows (we already know the session/column)
yRunRow = np.empty([m, n])
yRunRow[:] = np.NAN
# keep track of map segment id
yMapSegment = []
if self.segMap is not None:
yMapSegment = np.empty([m, n])
yMapSegment[:] = np.NAN
# 20171225, cPnt is overkill but until I rewrite REST
# to get list of stat (x,y,z,pDist, cPnt, cx, cy, cz) etc. etc.
cPnt = np.empty([m, n])
cPnt[:] = np.NAN
runIdxDim = 6
if pd['stacklist'] is not None and len(pd['stacklist'])>0:
myRange = pd['stacklist']
else:
myRange = range(n)
for j in myRange:
#print('*** getMapValues3() j:', j, "pd['segmentid']:", pd['segmentid'])
orig_df = self.stacks[j].stackdb
currSegmentID = []
if self.numMapSegments > 0:
if pd['segmentid'] >=0 :
currSegmentID = self.segRunMap[pd['segmentid'], j] # this only works for one segment -- NOT A LIST
#print(' currSegmentID:', currSegmentID)
if currSegmentID >= 0:
currSegmentID = int(currSegmentID)
# print 'getMapValues3() j:', j, 'currSegmentID:', currSegmentID
currSegmentID = [currSegmentID]
else:
currSegmentID = []
#print(' currSegmentID:', currSegmentID)
if pd['segmentid'] >= 0 and not currSegmentID:
# this session does not have segmentID that match
#print(' getMapValues3() skipping tp', j)
continue
goodIdx = self.runMap[:, j] # valid indices from runMap
#print goodIdx
runMap_idx = orig_df.index.isin(goodIdx) # series of boolean (Seems to play nice with nparray)
if pd['roitype']:
roiType_idx = orig_df['roiType'].isin(pd['roitype'])
runMap_idx = runMap_idx & roiType_idx
if currSegmentID:
segmentID_idx = orig_df['parentID'].isin(currSegmentID)
runMap_idx = runMap_idx & segmentID_idx
if not pd['plotbad']:
notBad_idx = ~orig_df['isBad'].isin([1])
runMap_idx = runMap_idx & notBad_idx
# final_df = orig_df.loc[runMap_idx]
final_df = orig_df.ix[runMap_idx]
finalIndexList = final_df.index.tolist()
# we have a list of valid stack centric index in runMap_idx
# reverse this back into run centric to set rows in runMap (xPlot, yPlot)
# finalRows = self.objMap[runIdxDim,final_df.index,j]
finalRows = self.objMap[runIdxDim, finalIndexList, j]
finalRows = finalRows.astype(int)
#print 'getMapValues3() final_df:', final_df
# convert to values at end
try:
if pd['xstat'] and pd['xstat'] != 'session':
pd['x'][finalRows, j] = final_df[pd['xstat']].values
if pd['ystat']:
pd['y'][finalRows, j] = final_df[pd['ystat']].values
if pd['zstat']:
pd['z'][finalRows, j] = final_df[pd['zstat']].values
except (KeyError, e):
print('getMapValues3() KeyError - reason ', str(e))
except:
print('getMapValues3() error in assignment')
# keep track of stack centric spine idx
yIdx[finalRows, j] = final_df.index.values
ySess[finalRows, j] = j
yRunRow[finalRows, j] = finalRows # final_df.index
# 20171119 finish this
#print 'a', final_df['parentID'].values.astype(int)
#print 'b', self.segMap[0, final_df['parentID'].values.astype(int), j]
if self.segMap is not None:
yMapSegment[finalRows, j] = self.segMap[0, final_df['parentID'].values.astype(int), j]
# 20171225
cPnt[finalRows, j] = final_df['cPnt'].values
if pd['xstat'] == 'session':
#print 'swapping x for session'
pd['x'][finalRows, j] = j #ySess[finalRows,j]
# strip out a nan rows, can't do this until we have gone through all sessions
# makes plotting way faster
ySess = ySess[~np.isnan(yIdx).all(axis=1)]
yRunRow = yRunRow[~np.isnan(yIdx).all(axis=1)]
if self.segMap is not None:
yMapSegment = yMapSegment[~np.isnan(yIdx).all(axis=1)] # added 20171220
cPnt = cPnt[~np.isnan(yIdx).all(axis=1)] # added 20171225
if pd['xstat']:
pd['x'] = pd['x'][~np.isnan(yIdx).all(axis=1)]
if pd['ystat']:
pd['y'] = pd['y'][~np.isnan(yIdx).all(axis=1)]
if pd['zstat']:
pd['z'] = pd['z'][~np.isnan(yIdx).all(axis=1)]
yIdx = yIdx[~np.isnan(yIdx).all(axis=1)] # do this last
stopTime = time.time()
print('mmMap.getMapValues3() took', round(stopTime - startTime, 2), 'seconds')
pd['stackidx'] = yIdx
pd['mapsess'] = ySess
pd['runrow'] = yRunRow
pd['mapsegment'] = yMapSegment
pd['cPnt'] = cPnt
if pd['getMapDynamics']:
# creates pd['dynamics']
pd = self.getMapDynamics(pd, thisMatrix=pd['stackidx'])
return pd
[docs] def getMapValues2(self, stat, roiType=['spineROI'], segmentID=[], plotBad=False, plotIntBad=False):
"""
Get values of a stack annotation across all stacks in the map.
Args:
stat (str): The stack annotation to get (corresponds to a column in mmStack.stackdb)
roiType (str): xxx
segmentID (list): xxx
plotBad (boolean): xxx
Returns:
2D numpy array of stat values. Each row is a run of objects connected across sessions,
columns are sessions, each [i][j] is a stat value
"""
#if roiType not in ROI_TYPES:
# errStr = 'error: mmMap.getMapValues2() stat "' + roiType + '" is not in ' + ','.join(ROI_TYPES)
# raise ValueError(errStr)
plotDict = newplotdict()
plotDict['roitype'] = roiType
plotDict['xstat'] = stat
plotDict['segmentid'] = segmentID
plotDict['plotbad'] = plotBad
plotDict['plotIntBad'] = plotIntBad
plotDict = self.getMapValues3(plotDict)
return plotDict['x']
def _buildRunMap(self, theMap, roiTypeID=None):
"""Internal function. Converts 3D objMap into a 2D run map. A run map must be float as it uses np.NaN
Args:
theMap: Either self.objMap or self.segMap
Returns:
A numpy ndarray run map
"""
idx = 0
next = 1
#nexttp = 2
prev = 3
#prevtp = 4
runIdx = 6 #if this is correct we can build really fast
nodeType = 9 # integer encoding type, spineROI==0
m = theMap.shape[1]
n = theMap.shape[2]
k = theMap.shape[0]
# reset
theMap[runIdx][:][:] = '-1'
# 20171222
# was this
#numRows = np.count_nonzero(~np.isnan(theMap[idx,:,0]))
#retRunMap = np.empty([numRows,n]) #, dtype=int)
# new
retRunMap = np.empty([1, n]) #, dtype=int) # start as one row in run map
retRunMap[:] = 'nan'
emptyRow = np.empty([1, n])
emptyRow[:] = 'nan'
# thisroitype = 'spineROI'
currRow = 0
for j in range(0,n): #sessions
# not loaded yet
#stackdb = self.stacks[j].stackdb
if j == 0:
firstSessionAdded = 0
for i in range(0,m):
#retRunMap[i,j] = 'nan'
# 20171221, if i just break on ! roiType (e.g. spine) then we get a run map without nan rows?
# we need to add an updated %runIdx as we do this, e.g. theMap[runIdx][i][j]= currRow
# new
#if theMap[idx,i,j]>=0 and stackdb[i][%roiType] == thisroitype:
# pass
#else:
# break
# was this
# if theMap[idx,i,j]>=0:
if theMap[idx,i,j]>=0 and (roiTypeID is None or theMap[nodeType][i][j] == roiTypeID):
pass
else:
continue
if j==0:
'''
# was this 20171222
currRow = i
#currRow = firstSessionAdded
# new one line 20171222
# retRunMap = np.vstack([retRunMap, emptyRow])
retRunMap[currRow, j] = i
# new
#theMap[runIdx,i,j] = currRow
'''
if firstSessionAdded == 0:
currRow = 0
firstSessionAdded += 1
else:
retRunMap = np.vstack([retRunMap, emptyRow])
currRow += 1
retRunMap[currRow, j] = i
# new
theMap[runIdx,i,j] = currRow
elif not (theMap[prev,i,j]>=0):
currRow += 1
retRunMap = np.vstack([retRunMap, emptyRow])
retRunMap[currRow, j] = i
# new
theMap[runIdx,i,j] = currRow
else:
continue
#retRunMap[currRow,j] = i
nextNode = theMap[next,i, j]
for k in range(j+1,n):
if nextNode >= 0:
retRunMap[currRow,k] = nextNode
# new, double check this
theMap[runIdx,int(nextNode),k] = currRow
else:
break
nextNode = theMap[next,int(nextNode),k]
return retRunMap
def _getStackSegmentID(self, mapSegmentNumber, sessIdx):
"""
Given a map centric segment index (row in segRunMap), tell us the stack centric segmentID for session sessIdx
Args:
mapSegmentNumber (int): Map centric segment index, row in segRunMap
sessIdx (int): Session number
Returns: int or nan: Stack centric segmentID or None if no corresponding segment in that session.
"""
stackSegment = np.nan
if self.segRunMap is not None:
stackSegment = self.segRunMap[mapSegmentNumber][sessIdx] # can be nan
if math.isnan(stackSegment):
return None
else:
return stackSegment
if __name__ == '__main__':
path = '../examples/exampleMaps/THet2a/THet2a.txt'
#path = '../examples/exampleMaps/rr30a/rr30a.txt'
path = '../examples/exampleMaps/BD_NGDG450/BD_NGDG450.txt'
print('path:', path)
m = mmMap(path)
print(m)
print('m.runMap.shape : ', m.runMap.shape)
for idx, stack in enumerate(m.stacks):
print('tp:', idx, 'n:', stack.stackdb.shape)
from pymapmanager.mmUtil import newplotdict
plotDict = newplotdict()
plotDict['roitype'] = m.defaultAnnotation
plotDict['xstat'] = 'days'
plotDict['ystat'] = 'pDist'
plotDict['zstat'] = 'ubssSum_int2' # 'sLen3d_int1' #swap in any stat you like, e.g. 'ubssSum_int2'
plotDict['segmentid'] = 0 #[0]
plotDict['getMapDynamics'] = True
plotDict = m.getMapValues3(plotDict)
print("\nplotDict['x'].shape : ", plotDict['x'].shape)
# test line
# THet2a has a stack but NO tracing and NO spines at session 0
session = 0
plotDict = m.stacks[session].line.getLineValues3(plotDict)
if plotDict['x']:
print("line plotDict['x'].shape:", plotDict['x'].shape)
print("line plotDict['sDist'].shape:", plotDict['sDist'].shape)
else:
print('__main__ did not find a line at session:', session)
print('\nm.mapInfo():')
mapInfo = m.mapInfo()
for key, value in mapInfo.iteritems():
print(key, value)
#from flask import jsonify
#print jsonify(mapInfo)
#import json
#print json.dumps(mapInfo)
# dynamics
#plotDict = m.getMapDynamics(plotDict)
#print plotDict['dynamics']