DM_numpy2odm.py
1 ## @package python.demo.DM_numpy2odm
2 #
3 # setting odm attributes from numpy objects
4 #
5 # The script uses the NumpyConverter functionality of pyDM. Each attribute must be provided in a separate numpy array
6 # which are 'combined' to a single dictionary object (also see DM_odm2numpy.py)
7 #
8 # The code computes normalized echo width values (between 0 and 1) based on single echoes, which is a pragmatic way of comparing
9 # values of different laser scanners (different wave length, different foot print size, etc.)
10 # (script works in python 2 and 3)
11 #
12 
13 from __future__ import print_function
14 
15 from opals import pyDM
16 import sys
17 import numpy
18 
19 odm = "fullwave.odm" # odm test file
20 
21 # pyDM.Datamanager.load parameter: filename(string), readOnly(bool) threadSafety(bool)
22 dm = pyDM.Datamanager.load(odm, False, False)
23 if not dm:
24  print("Unable to open ODM '" + odm + "'")
25  sys.exit(1)
26 
27 
28 # build layout for retrieving echo width values (subset of odm attributes)
29 lf = pyDM.AddInfoLayoutFactory()
30 type, inDM = lf.addColumn(dm, "EchoWidth", True); assert inDM == True
31 type, inDM = lf.addColumn(dm, "NrOfEchos", True); assert inDM == True
32 layoutRead = lf.getLayout()
33 
34 lf.addColumn(pyDM.ColumnType.float_, "_normalizedEchoWidth")
35 layoutWrite = lf.getLayout()
36 
37 print("Get odm echo width as numpy object...")
38 #create dictionary of numpy objects
39 numpyDict = pyDM.NumpyConverter.createNumpyDict(dm.sizePoint(),layoutRead,False)
40 print("len(numpyDict)=",len(numpyDict))
41 pointindex = dm.getPointIndex()
42 
43 #fill numpy dictionary with all leafs of the ODM point index
44 rowIdx = 0
45 count = float(pointindex.sizeLeaf())
46 for idx,leaf in enumerate(pointindex.leafs()):
47  print("%5.1f%% finished" % (idx/count*100.) )
48  rowIdx += pyDM.NumpyConverter.fillNumpyDict(numpyDict,rowIdx,leaf)
49 
50 print("100.0% finished.",rowIdx,"values have been converted")
51 
52 
53 print("\nCompute min max echo width for single echos using numpy...")
54 mask = numpyDict["NrOfEchos"] == 1 # generate single echo mask
55 minValue = (numpyDict["EchoWidth"][mask]).min()
56 maxValue = (numpyDict["EchoWidth"][mask]).max()
57 print("\tmin=%.2f" % minValue)
58 print("\tmax=%.2f" % maxValue)
59 
60 # compute parameter of linear transform function
61 k = 1./(maxValue-minValue)
62 d = -minValue*k
63 normalizedEchoWidth = numpyDict["EchoWidth"]*k+d
64 
65 # check if linear transform function
66 minCheck = (normalizedEchoWidth[mask]).min(); assert abs(minCheck) < 1e-10
67 maxCheck = (normalizedEchoWidth[mask]).max(); assert abs(maxCheck-1) < 1e-10
68 
69 #store normalized echo width values within the odm
70 storeDict = {}
71 storeDict["_normalizedEchoWidth"] = normalizedEchoWidth
72 print("\nStore normalised echo width values in ODM...")
73 for idx,leaf in enumerate(pointindex.leafs()):
74  print("%5.1f%% finished" % (idx/count*100.) )
75 
76  # pyDM.NumpyConverter.setFromNumpyDict( numpyDict, translators, leaf, layout, filter = None)
77  # for details on the function, please refer to the docu
78  pyDM.NumpyConverter.setFromNumpyDict(storeDict, [], leaf, layoutWrite) # we don't need translators in this case
79 
80  #mark leaf as changed/dirty that it will be written do disk again
81  leaf.setChanged(True)
82 
83 print("100.0% finished.")
84 
85 print("\nSave odm...")
86 dm.save()
87 print("finished")