You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
4.0 KiB

  1. import xarray as xr
  2. import numpy as np
  3. from collections import OrderedDict
  4. from functools import partial
  5. import copy
  6. def _read_globals_attrs(variable_attrs, context=None):
  7. """Combine attributes from different variables according to combine_attrs"""
  8. if not variable_attrs:
  9. # no attributes to merge
  10. return None
  11. from xarray.core.utils import equivalent
  12. result = {}
  13. dropped_attrs = OrderedDict()
  14. for attrs in variable_attrs:
  15. result.update(
  16. {
  17. key: value
  18. for key, value in attrs.items()
  19. if key not in result and key not in dropped_attrs.keys()
  20. }
  21. )
  22. result = {
  23. key: value
  24. for key, value in result.items()
  25. if key not in attrs or equivalent(attrs[key], value)
  26. }
  27. dropped_attrs.update(
  28. {
  29. key: []
  30. for key in attrs if key not in result
  31. }
  32. )
  33. for attrs in variable_attrs:
  34. dropped_attrs.update(
  35. {
  36. key: np.append(dropped_attrs[key], attrs[key])
  37. for key in dropped_attrs.keys()
  38. }
  39. )
  40. scan_attrs = OrderedDict()
  41. scan_length = []
  42. for attrs_key in dropped_attrs.keys():
  43. flag = True
  44. for key in scan_attrs.keys():
  45. if equivalent(scan_attrs[key], dropped_attrs[attrs_key]):
  46. flag = False
  47. result.update({attrs_key: key})
  48. break
  49. if flag:
  50. scan_attrs.update({
  51. attrs_key: dropped_attrs[attrs_key]
  52. })
  53. scan_length = np.append(scan_length, len(dropped_attrs[attrs_key]))
  54. result.update(
  55. {
  56. key: value
  57. for key, value in scan_attrs.items()
  58. }
  59. )
  60. result.update(
  61. {
  62. "scanAxis": list(scan_attrs.keys()),
  63. "scanAxisLength": scan_length,
  64. }
  65. )
  66. return result
  67. def _read_shot_number_from_hdf5(x):
  68. filePath = x.encoding["source"]
  69. shotNum = filePath.split("_")[-1].split("_")[-1].split(".")[0]
  70. return x.assign(shotNum=shotNum)
  71. def _assign_scan_axis_partial(x, datesetOfGlobal):
  72. scanAxis = datesetOfGlobal.scanAxis
  73. filePath = x.encoding["source"]
  74. shotNum = filePath.split("_")[-1].split("_")[-1].split(".")[0]
  75. x = x.assign(shotNum=shotNum)
  76. x = x.expand_dims(list(scanAxis))
  77. return x.assign_coords(
  78. {
  79. key: np.atleast_1d(datesetOfGlobal.attrs[key][int(shotNum)])
  80. for key in scanAxis
  81. }
  82. )
  83. def read_hdf5_file(filePath, group=None, datesetOfGlobal=None, preprocess=None, join="outer", parallel=True, engine="h5netcdf", phony_dims="access", **kwargs):
  84. kwargs.update(
  85. {
  86. 'join': join,
  87. 'parallel': parallel,
  88. 'engine': engine,
  89. 'phony_dims': phony_dims,
  90. 'group': group
  91. }
  92. )
  93. if datesetOfGlobal is None:
  94. datesetOfGlobal = xr.open_mfdataset(
  95. filePath,
  96. group="globals",
  97. concat_dim="fileNum",
  98. combine="nested",
  99. preprocess=_read_shot_number_from_hdf5,
  100. engine="h5netcdf",
  101. phony_dims="access",
  102. combine_attrs=_read_globals_attrs,
  103. parallel=True, )
  104. _assgin_scan_axis = partial(_assign_scan_axis_partial, datesetOfGlobal=datesetOfGlobal)
  105. if preprocess is None:
  106. kwargs.update({'preprocess':_assgin_scan_axis})
  107. else:
  108. kwargs.update({'preprocess':preprocess})
  109. ds = xr.open_mfdataset(filePath, **kwargs)
  110. newDimKey = np.append(['x', 'y', 'z'], [ chr(i) for i in range(97, 97+23)])
  111. oldDimKey = np.sort(
  112. [
  113. key
  114. for key in ds.dims
  115. if not key in datesetOfGlobal.scanAxis
  116. ]
  117. )
  118. renameDict = {
  119. oldDimKey[j]: newDimKey[j]
  120. for j in range(len(oldDimKey))
  121. }
  122. ds = ds.rename_dims(renameDict)
  123. ds.attrs = copy.deepcopy(datesetOfGlobal.attrs)
  124. return ds