mirror of
https://github.com/JHUAPL/kaiju.git
synced 2026-01-08 22:58:05 -05:00
208 lines
5.9 KiB
Python
208 lines
5.9 KiB
Python
#Various routines to help scripts that create XMF files from H5 data
|
|
import numpy as np
|
|
import h5py
|
|
import kaipy.kaiH5 as kh5
|
|
import xml.etree.ElementTree as et
|
|
import kaipy.kdefs as kdefs
|
|
#Add grid info to step
|
|
#Geom is topology subelement, iDims is grid size string
|
|
def AddGrid(fname,Geom,iDims,coordStrs):
|
|
|
|
for coordStr in coordStrs:
|
|
xC = et.SubElement(Geom,"DataItem")
|
|
xC.set("Dimensions",iDims)
|
|
xC.set("NumberType","Float")
|
|
xC.set("Precision","4")
|
|
xC.set("Format","HDF")
|
|
|
|
text = fname+":/"+coordStr
|
|
xC.text = text
|
|
|
|
#Add data to slice
|
|
def AddData(Grid,fname,vID,vLoc,xDims,s0=None):
|
|
if (vLoc != 'Other'):
|
|
#Add attribute
|
|
vAtt = et.SubElement(Grid,"Attribute")
|
|
vAtt.set("Name",vID)
|
|
vAtt.set("AttributeType","Scalar")
|
|
vAtt.set("Center",vLoc)
|
|
#Add data item
|
|
aDI = et.SubElement(vAtt,"DataItem")
|
|
aDI.set("Dimensions",xDims)
|
|
aDI.set("NumberType","Float")
|
|
aDI.set("Precision","4")
|
|
aDI.set("Format","HDF")
|
|
if (s0 is None):
|
|
aDI.text ="%s:/%s"%(fname,vID)
|
|
else:
|
|
aDI.text = "%s:/Step#%d/%s"%(fname,s0,vID)
|
|
|
|
#Add data item to passed element
|
|
def AddDI(elt,h5F,nStp,cDims,vId):
|
|
aDI = et.SubElement(elt,"DataItem")
|
|
aDI.set("Dimensions",cDims)
|
|
aDI.set("NumberType","Float")
|
|
aDI.set("Precision","4")
|
|
aDI.set("Format","HDF")
|
|
if (nStp>=0):
|
|
aDI.text = "%s:/Step#%d/%s"%(h5F,nStp,vId)
|
|
else:
|
|
aDI.text ="%s:/%s"%(h5F,vId)
|
|
|
|
#Get root variables
|
|
def getRootVars(fname,gDims):
|
|
#Dims = kh5.getDims(fname,doFlip=False) #Do kji ordering
|
|
with h5py.File(fname,'r') as hf:
|
|
vIds = []
|
|
vLocs = []
|
|
for k in hf.keys():
|
|
#Don't include stuff that starts with step or X,Y,Z
|
|
vID = str(k)
|
|
doV = True
|
|
if ("Step" in vID or kdefs.grpTimeCache in vID ):
|
|
doV = False
|
|
if ((vID == "X") or (vID=="Y") or (vID=="Z")):
|
|
doV = False
|
|
if (doV):
|
|
Nv = hf[k].shape
|
|
vLoc = getLoc(gDims,Nv)
|
|
if (vLoc != "Other"):
|
|
vIds.append(vID)
|
|
vLocs.append(vLoc)
|
|
else:
|
|
print("Excluding %s"%(vID))
|
|
|
|
return vIds,vLocs
|
|
|
|
#Get variables in initial Step
|
|
def getVars(fname,gId,gDims,recursive=False):
|
|
|
|
def getVarName(gId, k, recursive):
|
|
if recursive:
|
|
# Want to keep the group name, since all vars need to be at the same level in xdmf
|
|
spl = gId.split('/')
|
|
return '/'.join(spl[1:]) + '/' + str(k)
|
|
else:
|
|
return str(k)
|
|
|
|
|
|
with h5py.File(fname,'r') as hf:
|
|
stp0 = hf[gId]
|
|
vIds = []
|
|
vLocs = []
|
|
for k in stp0.keys():
|
|
vID = getVarName(gId,k,recursive)
|
|
|
|
# If its a group, recursively call this function to get to the vars and add them to the list
|
|
if type(stp0[k]) == h5py._hl.group.Group:
|
|
vIdR, vLR = getVars(fname, gId+'/'+k, gDims, recursive=True)
|
|
for vi, vl in zip(vIdR, vLR):
|
|
vIds.append(vi)
|
|
vLocs.append(vl)
|
|
else:
|
|
Nv = stp0[k].shape
|
|
vLoc = getLoc(gDims,Nv)
|
|
if (vLoc != "Other"):
|
|
vIds.append(vID)
|
|
vLocs.append(vLoc)
|
|
else:
|
|
print("Excluding %s"%(vID))
|
|
return vIds,vLocs
|
|
|
|
def AddVectors(Grid,fname,vIds,cDims,vDims,Nd,nStp):
|
|
#Velocity (2D)
|
|
if ( (Nd == 2) and ("Vx" in vIds) and ("Vy" in vIds) ):
|
|
vAtt = et.SubElement(Grid,"Attribute")
|
|
vAtt.set("Name","VecV")
|
|
vAtt.set("AttributeType","Vector")
|
|
vAtt.set("Center","Cell")
|
|
fDI = et.SubElement(vAtt,"DataItem")
|
|
fDI.set("ItemType","Function")
|
|
fDI.set("Dimensions",vDims)
|
|
fDI.set("Function","JOIN($0 , $1)")
|
|
AddDI(fDI,fname,nStp,cDims,"Vx")
|
|
AddDI(fDI,fname,nStp,cDims,"Vy")
|
|
|
|
#Velocity (3D)
|
|
if ( (Nd == 3) and ("Vx" in vIds) and ("Vy" in vIds) and ("Vz" in vIds)):
|
|
vAtt = et.SubElement(Grid,"Attribute")
|
|
vAtt.set("Name","VecV")
|
|
vAtt.set("AttributeType","Vector")
|
|
vAtt.set("Center","Cell")
|
|
fDI = et.SubElement(vAtt,"DataItem")
|
|
fDI.set("ItemType","Function")
|
|
fDI.set("Dimensions",vDims)
|
|
fDI.set("Function","JOIN($0 , $1 , $2)")
|
|
AddDI(fDI,fname,nStp,cDims,"Vx")
|
|
AddDI(fDI,fname,nStp,cDims,"Vy")
|
|
AddDI(fDI,fname,nStp,cDims,"Vz")
|
|
|
|
#Magnetic field (2D)
|
|
if ( (Nd == 2) and ("Bx" in vIds) and ("By" in vIds) ):
|
|
vAtt = et.SubElement(Grid,"Attribute")
|
|
vAtt.set("Name","VecB")
|
|
vAtt.set("AttributeType","Vector")
|
|
vAtt.set("Center","Cell")
|
|
fDI = et.SubElement(vAtt,"DataItem")
|
|
fDI.set("ItemType","Function")
|
|
fDI.set("Dimensions",vDims)
|
|
fDI.set("Function","JOIN($0 , $1)")
|
|
AddDI(fDI,fname,nStp,cDims,"Bx")
|
|
AddDI(fDI,fname,nStp,cDims,"By")
|
|
|
|
if ( (Nd == 3) and ("Bx" in vIds) and ("By" in vIds) and ("Bz" in vIds)):
|
|
vAtt = et.SubElement(Grid,"Attribute")
|
|
vAtt.set("Name","VecB")
|
|
vAtt.set("AttributeType","Vector")
|
|
vAtt.set("Center","Cell")
|
|
fDI = et.SubElement(vAtt,"DataItem")
|
|
fDI.set("ItemType","Function")
|
|
fDI.set("Dimensions",vDims)
|
|
fDI.set("Function","JOIN($0 , $1 , $2)")
|
|
AddDI(fDI,fname,nStp,cDims,"Bx")
|
|
AddDI(fDI,fname,nStp,cDims,"By")
|
|
AddDI(fDI,fname,nStp,cDims,"Bz")
|
|
#Decide on centering
|
|
def getLoc(gDims,vDims):
|
|
vDims = np.array(vDims,dtype=int)
|
|
dimLocs = []
|
|
if len(gDims) != len(vDims):
|
|
return "Other"
|
|
for d in range(len(gDims)):
|
|
Ngd = gDims[d]-1
|
|
Nvd = vDims[d]
|
|
if Ngd == Nvd:
|
|
dimLocs.append("Cell")
|
|
elif Ngd == Nvd-1:
|
|
dimLocs.append("Node")
|
|
else:
|
|
dimLocs.append("Other")
|
|
|
|
if "Other" in dimLocs:
|
|
return "Other"
|
|
#If all the same, we have consensus
|
|
if all(x == dimLocs[0] for x in dimLocs):
|
|
return dimLocs[0]
|
|
else:
|
|
return "Other"
|
|
|
|
def addHyperslab(Grid,vName,dSetDimStr,vdimStr,startStr,strideStr,numStr,origDSetDimStr,fileText):
|
|
vAtt = et.SubElement(Grid, "Attribute")
|
|
vAtt.set("Name",vName)
|
|
vAtt.set("AttributeType","Scalar")
|
|
vAtt.set("Center","Node")
|
|
slabDI = et.SubElement(vAtt, "DataItem")
|
|
slabDI.set("ItemType","HyperSlab")
|
|
slabDI.set("Dimensions",dSetDimStr)
|
|
slabDI.set("Type","HyperSlab") # Not sure if redundant, but it works
|
|
cutDI = et.SubElement(slabDI,"DataItem")
|
|
cutDI.set("Dimensions",vdimStr)
|
|
cutDI.set("Format","XML")
|
|
cutDI.text = "\n{}\n{}\n{}\n".format(startStr,strideStr,numStr)
|
|
datDI = et.SubElement(slabDI,"DataItem")
|
|
datDI.set("Dimensions",origDSetDimStr)
|
|
datDI.set("DataType","Float")
|
|
datDI.set("Precision","4")
|
|
datDI.set("Format","HDF")
|
|
datDI.text = fileText
|