In [72]:
# import stuff
import sys,os
import numpy as np
sys.path.append( os.environ["PYTHONSCRIPT_DIR"] )
import matplotlib as mpl
mpl.use('Agg')
import PlotSettings as pS
pS.loadPlotSettings(mpl)
lineSettings = pS.generalSettings.defaultLineSettings
from Tools.Parsers.SimDataReader import SimDataConsolidate
from Tools.Parsers.Utilities import parseNDArray
sys.path.append( os.environ["HPCJOBCONFIGURATOR_DIR"])
from HPCJobConfigurator.jobGenerators.commonFunctions import CommonFunctions as cf
import matplotlib.cm as cm
import matplotlib.pyplot as plt
import matplotlib.colors as colors
mpl.get_configdir()
%load_ext autoreload
%autoreload 2
In [73]:
import glob2, re
from matplotlib.ticker import MultipleLocator
import io
plt.close("all")
def loadIniFile(file):
# no interpolation is done!
import configparser
config = configparser.ConfigParser(interpolation=None)
config.read(file)
return config
def loadData(files,dt,dtParse):
import xml.etree.ElementTree as ET
dataPerFile = []
for f in files:
print("Parsing file: ", f)
root = ET.parse(f["file"])
# stack all data together
size = len(root.findall("State"))
dataArray = np.ndarray((size,), dtype=dt)
for idx,s in enumerate(root.iter("State")):
dataArray[idx] = parseNDArray(s.text,dt=dtParse)
dataPerFile.append(dict(f,data=dataArray))
return dataPerFile
def generateColorMap(l,name):
jet = colorMap = plt.get_cmap(name)
cNorm = colors.Normalize(vmin=0, vmax=l)
scalarMap = cm.ScalarMappable(norm=cNorm, cmap=colorMap)
return scalarMap;
# Indices for data in file: ===================
dataTypeRow = [('time', float), ('stateIdx', int), ('bodyCount', int), ('bodyCountN', float)]
dataTypeRowParse = [('time', float), ('stateIdx', int), ('bodyCount', int)]
# =====================================
# Plot Options =======================
thisRootFolder = "../"
simulationJobsFolder = os.path.join(thisRootFolder,"../SimulationJobs")
nBodies = 1e6;
corrExperimentNr = 5;
oneSidePlot = True
labelLength = "B-14\hspace{0.2em}"
if oneSidePlot:
figureSize= (pS.cm2inch(15.8),pS.cm2inch(10))
legendProps = dict(prop=dict(size=10),borderpad=0.35,labelspacing=0.2,handletextpad=0.3,markerscale=1,borderaxespad=1)
else:
labelLength = 5.5 # für factor 1.0 -> 5.5
figureSize= (pS.cm2inch(8),pS.cm2inch(6))
legendProps = dict(prop=dict(size=6),borderpad=0.35,labelspacing=0.1,handletextpad=0.3,markerscale=1)
legendLineScale = 2
studyCMapName = "spectral"
xAxisLabelMinorSpacing = 0.1
xAxisLabelMajorSpacing = 0.5
studyJobIniFile = os.path.join( simulationJobsFolder, "StudyConfig.ini")
class LabelFormatter:
def __init__(self,muList):
self.muList = muList
def __call__(self,studyNr, param=True,labelLength = labelLength):
if studyNr == 15:
studyNr = 14
add=r"$\overbar{\textnormal{B}}$"
else:
add="B"
if param:
return r"\parbox{\widthof{%s}}{%s-%i}, $\mu\!=\!%.1f$" % (labelLength,add,studyNr,self.muList[studyNr])
else:
return r"\parbox{\widthof{%s}}{%s-%i}" % (labelLength,add,studyNr)
experimentSettingsFile = os.path.join( thisRootFolder, "data/ExperimentSettings.json" )
expPlotOpts = dict(ls="-",color='black', lw=lineSettings["thick"])
def makeStudyPlotOptions(file,idx, color):
cc = 0.6
c = [cc]*3
if idx != 15:
return dict(
lines = dict(ls="-",color=color, lw=lineSettings["thin"]),
linesduennG = dict(ls="-",color=c,lw=lineSettings["extra-thin"]),
linesduenn = dict(ls="-",color=color, lw=lineSettings["thick"]),
points = dict(marker='o',ms=pS.defaultMarkerSize,markerfacecolor=color, markeredgewidth=0,markeredgecolor=None),
pointsBig = dict(marker='o',s=pS.defaultMarkerSize**2,color=color)
)
else:
c = [0.0]*3
return dict(
lines = dict(ls="--",color=c, lw=lineSettings["extra-thin"]),
linesduennG = dict(ls="-",color=c,lw=lineSettings["extra-thin"]),
linesduenn = dict(ls="-",color=c, lw=lineSettings["extra-thin"]),
points = dict(marker='o',ms=pS.defaultMarkerSize,markerfacecolor=c, markeredgewidth=0,markeredgecolor=None),
pointsBig = dict(marker='o',s=pS.defaultMarkerSize**2,color=c)
)
# =====================================
# Glob all xml files
filePaths = sorted(glob2.glob("*.xml"))
files = []
for f in filePaths:
m=re.match(".*P-(\d*)-",f);
if(m):
nr = int(m.group(1))
files.append({"file":f,"studyNr":nr})
files.sort(key=lambda x: x["studyNr"])
# Load ExperimentSettingsFile
expSet = cf.jsonLoad(experimentSettingsFile)
timeEntryExperiment = expSet["experiments"]["%i"%corrExperimentNr]["deltaTimeStartTillEntry"]
timeEntryTillFinal = expSet["experiments"]["%i"%corrExperimentNr]["deltaTimeEntryTillFinal"]
# Load SimulationJob config ini
studyConfig = loadIniFile(studyJobIniFile)["ParameterStudy"]
muList=cf.jsonParse(studyConfig["muList"])
labelFormatter = LabelFormatter(muList)
# Load Data
files = loadData(files,dataTypeRow,dataTypeRowParse)
colorMap = generateColorMap(len(files),studyCMapName).to_rgba
#Colormap
for fIdx,f in enumerate(files):
f["plotOpts"] = makeStudyPlotOptions(f,fIdx,colorMap(fIdx))
# Remove over all files (time differences which are zero (multiple simulation files))
for i,f in enumerate(files):
d=np.nonzero(np.diff(f["data"]["time"]))
mask=np.hstack([ d[0],[len(f["data"]["time"])-1] ])
# mask all data
f["data"] = f["data"][mask]
In [74]:
# Plot Entry Count (count of bodies entering the lower slope) ====================
fig = plt.figure(figsize=figureSize)
ax = fig.add_subplot(111)
ax.set_axisbelow(True)
for i,f in enumerate(reversed(files)):
if f["studyNr"] != 15:
d = f["data"]
ax.axvline(x=d["time"][-1], ymin=0.00, ymax=0.05, **f["plotOpts"]["linesduenn"])
ax.plot([d["time"][-1]]*2, [0.0,1], **f["plotOpts"]["linesduennG"])
ax.plot(d["time"][-1], 1 , **f["plotOpts"]["points"] )
for i,f in enumerate(reversed(files)):
if f["studyNr"] != 15:
d = f["data"]
d["bodyCountN"] = d["bodyCount"] / nBodies # norm the data
ax.plot(d["time"], d["bodyCountN"], label=labelFormatter(f["studyNr"],False), **f["plotOpts"]["lines"])
leg=ax.legend(loc=2,scatterpoints=1,**legendProps)
for legobj in leg.legendHandles:
legobj.set_linewidth(legendLineScale*legobj.get_linewidth())
ax.set_ylabel(r"$F^{n_{b,S}}(t)$")
ax.set_xlabel(r"time $t$ [s]")
# ax.set_title("Simulation Study with 3 Trees")
minorLocatorX = MultipleLocator(xAxisLabelMinorSpacing)
ax.xaxis.set_minor_locator(minorLocatorX)
minorLocatorY = MultipleLocator(0.1)
ax.yaxis.set_minor_locator(minorLocatorY)
majorLocatorX = MultipleLocator(0.5)
ax.xaxis.set_major_locator(MultipleLocator(xAxisLabelMajorSpacing))
majorLocatorY = MultipleLocator(1)
ax.yaxis.set_major_locator(majorLocatorY)
ax.grid(which='minor', alpha=0.15, linestyle=':')
#ax.grid(which='major', alpha=0.4, linestyle=':')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.margins(0.05, 0.05)
pS.defaultFormatAxes(ax)
fig.tight_layout(pad=0.3);
plt.subplots_adjust(top=0.91, wspace=0, hspace=0)
plt.savefig("bodyCountPlot.pdf",bbox_inches = 'tight',
pad_inches = 0.05)
# =======================================================================================
# Plot flow through (derivative of body count)
fig = plt.figure(figsize=figureSize)
ax = fig.add_subplot(111)
ax.ticklabel_format(style='sci',scilimits=(0,0),axis='y')
ax.set_axisbelow(True)
for i,f in enumerate(files):
d = f["data"]
diff = np.diff( d["bodyCount"] / d["bodyCount"][-1]) # normed flow (of total body count)
diff = np.hstack([diff,0])
plt.plot(d["time"][:len(diff)], diff, label=labelFormatter(f["studyNr"],True), **f["plotOpts"]["lines"])
if f["studyNr"] != 15:
ax.plot(d["time"][len(diff)-1], 0 , **f["plotOpts"]["points"] )
# Mark experiment
ax.axvline(x=timeEntryExperiment, lw=2, zorder=1, color=[0.7]*3 )
ax.axvline(x=timeEntryExperiment+timeEntryTillFinal, lw=2, zorder=1.2, color=[0.7]*3 )
leg=ax.legend(loc=1,scatterpoints=1,**legendProps)
for legobj in leg.legendHandles:
legobj.set_linewidth(legendLineScale*legobj.get_linewidth())
ax.set_ylabel(r"$f^{n_{b,S}}(t)$ [1/s]")
ax.set_xlabel(r"time $t$ [s]")
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# ax.set_title("Simulation Study with 3 Trees")
ax.margins(0.08, 0.05)
ax.xaxis.set_minor_locator(minorLocatorX)
ax.xaxis.set_major_locator(majorLocatorX)
ax.yaxis.set_minor_locator(MultipleLocator(0.001))
ax.grid(which='minor', alpha=0.15, linestyle=':')
pS.defaultFormatAxes(ax)
fig.tight_layout(pad=0.3);
# plt.subplots_adjust(left=0.1, bottom=0.2, right=0.99, top=0.91, wspace=0, hspace=0)
plt.savefig("bodyCountFlowPlot.pdf",bbox_inches = 'tight',
pad_inches = 0.05)
In [75]:
# Plot friction coefficient against end time :-)
fig = plt.figure(figsize=figureSize)
ax = fig.add_subplot(111)
ax.set_ylabel(r"flow duration $\Delta t_{f}$ [s]")
ax.set_xlabel(r"friction coefficient $\mu$")
ax.set_axisbelow(True)
x=[]
y=[]
for i,f in enumerate(files):
if f["studyNr"] != 15:
d = f["data"]
# search 90% time
idx90Quantil = np.min(np.where(d["bodyCountN"]>=0.95))
idx0Quantil = np.min(np.where(d["bodyCountN"]>0.01))
x.append(muList[f["studyNr"]])
y.append(d["time"][idx90Quantil]-d["time"][idx0Quantil])
ax.scatter(x[-1],y[-1] ,label=labelFormatter(f["studyNr"],True),zorder=1.3,**f["plotOpts"]["pointsBig"])
ax.plot(x,y, color="k",lw=lineSettings["semi-thick"],zorder=1.2)
ax.legend(loc=4,scatterpoints=1,**legendProps)
ax.margins(0.05, 0.05)
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_minor_locator(MultipleLocator(0.2))
ax.yaxis.set_minor_locator(MultipleLocator(0.1))
ax.grid(which='minor', alpha=0.4, linestyle=':')
pS.defaultFormatAxes(ax)
fig.tight_layout(pad=0.3)
plt.subplots_adjust(top=0.91, wspace=0, hspace=0)
plt.savefig("bodyCountTimePlot.pdf",bbox_inches = 'tight',
pad_inches = 0.05)
In [76]:
# Glob all .dat.gz files
filePaths = sorted(glob2.glob("*.dat.gz"))
simDatFiles = []
for f in filePaths:
m=re.match(".*P-(\d*)",f);
if(m):
nr = int(m.group(1))
simDatFiles.append({"file":f,"studyNr":nr})
reader = SimDataConsolidate()
simDatFiles = sorted(simDatFiles, key=lambda x: x["studyNr"])
for f in simDatFiles:
if f["studyNr"] != 15:
reader.loadCombined(f["file"])
f["simData"] = reader.simDataList
In [77]:
for fIdx,f in enumerate(simDatFiles):
f["plotOpts"] = makeStudyPlotOptions(f,fIdx,colorMap(fIdx))
# Plot all contacts of each study
fig = plt.figure(figsize=figureSize)
ax = fig.add_subplot(111)
ax.set_ylabel(r"number of contacts")
ax.set_xlabel(r"time [s]")
ax.ticklabel_format(style='sci',scilimits=(0,0),axis='y')
for f in simDatFiles:
if "simData" in f:
d = f["simData"]
ax.plot(d["Total"]["SimulationTime"],d["Total"]["nContacts"],
label=labelFormatter(f["studyNr"],False), **f["plotOpts"]["lines"])
ax.margins(0.05, 0.05)
ax.legend(loc=1,scatterpoints=1,**legendProps)
leg=ax.legend(loc=1,scatterpoints=1,**legendProps)
for legobj in leg.legendHandles:
legobj.set_linewidth(legendLineScale*legobj.get_linewidth())
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_minor_locator(MultipleLocator(0.2))
ax.yaxis.set_minor_locator(MultipleLocator(0.25e6))
ax.grid(which='minor', alpha=0.15, linestyle=':')
pS.defaultFormatAxes(ax)
fig.tight_layout(pad=0.3)
plt.subplots_adjust(top=0.91, wspace=0, hspace=0)
plt.savefig("contactsTimePlot.pdf",bbox_inches = 'tight',
pad_inches = 0.05)
In [78]:
entryTimeSettings = {}
# Determine all enterTimes
bodyThresh = 150 # bodies
entryTimeSettings["general"] = dict(bodyThreshold=bodyThresh)
studies = entryTimeSettings["studies"] = {}
files.reverse()
for f in files:
d= f["data"]
idx = np.argmax(d["bodyCount"] > 150)
idx = idx -1 if idx >=0 else 0
studies[f["studyNr"]] = dict(
entryTime = float(d["time"][idx]),
entryStateIdx = int(d["stateIdx"][idx]),
entryBodyCount = int(d["bodyCount"][idx]),
finalTime = float(d["time"][-1]),
finalStateIdx = int(d["stateIdx"][-1]),
finalBodyCount = int(d["bodyCount"][-1])
)
f=open("StudyEntryData.json","w")
cf.jsonDump(entryTimeSettings,f,compactly=False,sort_keys=True);
f.close()
In [ ]: