DM_numpy2odm.py
## @package python.DM_numpy2odm
## @brief unkown python script prefix=autobuild.swdvlp64.opals.distro.demo
#
# setting odm attributes from numpy objects
#
# The script uses the NumpyConverter functionality of pyDM. Each attribute must be provided in a separate numpy array
# which are 'combined' to a single dictionary object (also see DM_odm2numpy.py)
#
# The code computes normalized echo width values (between 0 and 1) based on single echoes, which is a pragmatic way of comparing
# values of different laser scanners (different wave length, different foot print size, etc.)
# (script works in python 2 and 3)
#
from __future__ import print_function
from opals import pyDM
import sys
import numpy
odm = "fullwave.odm" # odm test file
# pyDM.Datamanager.load parameter: filename(string), readOnly(bool) threadSafety(bool)
dm = pyDM.Datamanager.load(odm, False, False)
if not dm:
print("Unable to open ODM '" + odm + "'")
sys.exit(1)
# build layout for retrieving echo width values (subset of odm attributes)
lf = pyDM.AddInfoLayoutFactory()
type, inDM = lf.addColumn(dm, "EchoWidth", True); assert inDM == True
type, inDM = lf.addColumn(dm, "NrOfEchos", True); assert inDM == True
layoutRead = lf.getLayout()
lf.addColumn(pyDM.ColumnType.float_, "_normalizedEchoWidth")
layoutWrite = lf.getLayout()
print("Get odm echo width as numpy object...")
#create dictionary of numpy objects
numpyDict = pyDM.NumpyConverter.createNumpyDict(dm.sizePoint(),layoutRead,False)
print("len(numpyDict)=",len(numpyDict))
pointindex = dm.getPointIndex()
#fill numpy dictionary with all leafs of the ODM point index
rowIdx = 0
count = float(pointindex.sizeLeaf())
for idx,leaf in enumerate(pointindex.leafs()):
print("%5.1f%% finished" % (idx/count*100.) )
rowIdx += pyDM.NumpyConverter.fillNumpyDict(numpyDict,rowIdx,leaf)
print("100.0% finished.",rowIdx,"values have been converted")
print("\nCompute min max echo width for single echos using numpy...")
mask = numpyDict["NrOfEchos"] == 1 # generate single echo mask
minValue = (numpyDict["EchoWidth"][mask]).min()
maxValue = (numpyDict["EchoWidth"][mask]).max()
print("\tmin=%.2f" % minValue)
print("\tmax=%.2f" % maxValue)
# compute parameter of linear transform function
k = 1./(maxValue-minValue)
d = -minValue*k
normalizedEchoWidth = numpyDict["EchoWidth"]*k+d
# check if linear transform function
minCheck = (normalizedEchoWidth[mask]).min(); assert abs(minCheck) < 1e-10
maxCheck = (normalizedEchoWidth[mask]).max(); assert abs(maxCheck-1) < 1e-10
#store normalized echo width values within the odm
storeDict = {}
storeDict["_normalizedEchoWidth"] = normalizedEchoWidth
print("\nStore normalised echo width values in ODM...")
for idx,leaf in enumerate(pointindex.leafs()):
print("%5.1f%% finished" % (idx/count*100.) )
# pyDM.NumpyConverter.setFromNumpyDict( numpyDict, translators, leaf, layout, filter = None)
# for details on the function, please refer to the docu
pyDM.NumpyConverter.setFromNumpyDict(storeDict, [], leaf, layoutWrite) # we don't need translators in this case
#mark leaf as changed/dirty that it will be written do disk again
leaf.setChanged(True)
print("100.0% finished.")
print("\nSave odm...")
dm.save()
print("finished")