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.

160 lines
5.2 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. import numpy as np
  2. import xarray as xr
  3. import copy
  4. class ImageAnalyser():
  5. def __init__(self) -> None:
  6. self._image_name = {
  7. 'atoms': 'atoms',
  8. 'background': 'background',
  9. 'dark': 'dark',
  10. 'OD':'OD',
  11. }
  12. self._center = None
  13. self._span = None
  14. self._fraction = None
  15. @property
  16. def image_name(self):
  17. return self._image_name
  18. @image_name.setter
  19. def image_name(self, value):
  20. self._image_name.update(value)
  21. @property
  22. def center(self):
  23. return self._center
  24. @center.setter
  25. def center(self, value):
  26. self._center = value
  27. @property
  28. def span(self):
  29. return self._span
  30. @span.setter
  31. def span(self, value):
  32. self._span = value
  33. @property
  34. def fraction(self):
  35. return self._fraction
  36. @fraction.setter
  37. def fraction(self, value):
  38. self._fraction = value
  39. def get_offset_from_corner(self, dataArray, x_fraction=None, y_fraction=None, fraction=None, xAxisName='x', yAxisName='y'):
  40. if fraction is None:
  41. if x_fraction is None:
  42. x_fraction = self._fraction[0]
  43. if y_fraction is None:
  44. y_fraction = self._fraction[1]
  45. else:
  46. x_fraction = fraction[0]
  47. y_fraction = fraction[1]
  48. x_number = dataArray[xAxisName].shape[0]
  49. y_number = dataArray[yAxisName].shape[0]
  50. mean = dataArray.isel(x=slice(0, int(x_number * x_fraction)), y=slice(0 , int(y_number * y_fraction))).mean(dim=[xAxisName, yAxisName])
  51. mean += dataArray.isel(x=slice(0, int(x_number * x_fraction)), y=slice(int(y_number - y_number * y_fraction) , int(y_number))).mean(dim=[xAxisName, yAxisName])
  52. mean += dataArray.isel(x=slice(int(x_number - x_number * x_fraction) , int(x_number)), y=slice(0 , int(y_number * y_fraction))).mean(dim=[xAxisName, yAxisName])
  53. mean += dataArray.isel(x=slice(int(x_number - x_number * x_fraction) , int(x_number)), y=slice(int(y_number - y_number * y_fraction) , int(y_number))).mean(dim=[xAxisName, yAxisName])
  54. return mean / 4
  55. def substract_offset(self, dataArray, **kwargs):
  56. res = dataArray - self.get_offset_from_corner(dataArray, **kwargs)
  57. res.attrs = copy.copy(dataArray.attrs)
  58. return res
  59. def crop_image(self, dataSet, center=None, span=None):
  60. if center is None:
  61. center = self._center
  62. if span is None:
  63. span = self._span
  64. x_start = int(center[0] - span[0] / 2)
  65. x_end = int(center[0] + span[0] / 2)
  66. y_end = int(center[1] + span[1] / 2)
  67. y_start = int(center[1] - span[1] / 2)
  68. dataSet.attrs['x_start'] = x_start
  69. dataSet.attrs['x_end'] = x_end
  70. dataSet.attrs['y_end'] = y_end
  71. dataSet.attrs['y_start'] = y_start
  72. dataSet.attrs['x_center'] = center[0]
  73. dataSet.attrs['y_center'] = center[1]
  74. dataSet.attrs['x_span'] = span[0]
  75. dataSet.attrs['y_span'] = span[1]
  76. if isinstance(dataSet, type(xr.Dataset())):
  77. for key in list(dataSet.data_vars):
  78. dataSet[key].attrs['x_start'] = x_start
  79. dataSet[key].attrs['x_end'] = x_end
  80. dataSet[key].attrs['y_end'] = y_end
  81. dataSet[key].attrs['y_start'] = y_start
  82. dataSet[key].attrs['x_center'] = center[0]
  83. dataSet[key].attrs['y_center'] = center[1]
  84. dataSet[key].attrs['x_span'] = span[0]
  85. dataSet[key].attrs['y_span'] = span[1]
  86. return dataSet.isel(x=slice(x_start, x_end), y=slice(y_start, y_end))
  87. def get_OD(self, imageAtom, imageBackground, imageDrak):
  88. numerator = np.atleast_1d(imageBackground - imageDrak)
  89. denominator = np.atleast_1d(imageAtom - imageDrak)
  90. numerator[numerator == 0] = 1
  91. denominator[denominator == 0] = 1
  92. imageOD = np.abs(np.divide(denominator, numerator))
  93. imageOD= -np.log(imageOD)
  94. if len(imageOD) == 1:
  95. return imageOD[0]
  96. else:
  97. return imageOD
  98. def get_Ncount(self, dataSet, dim=['x', 'y'], **kwargs):
  99. return dataSet.sum(dim=['x', 'y'], **kwargs)
  100. def get_absorption_images(self, dataSet, dask='allowed', keep_attrs=True, **kwargs):
  101. kwargs.update(
  102. {
  103. 'dask': dask,
  104. 'keep_attrs': keep_attrs,
  105. }
  106. )
  107. dataSet = dataSet.assign(
  108. {
  109. self._image_name['OD']: xr.apply_ufunc(self.get_OD, dataSet[self._image_name['atoms']], dataSet[self._image_name['background']], dataSet[self._image_name['dark']], **kwargs)
  110. }
  111. )
  112. # dataSet[self._image_name['OD']].attrs.update(dataSet.attrs)
  113. return dataSet
  114. def remove_background(self, dataSet, dask='allowed', keep_attrs=True, **kwargs):
  115. kwargs.update(
  116. {
  117. 'dask': dask,
  118. 'keep_attrs': keep_attrs,
  119. }
  120. )
  121. xr.apply_ufunc(self.get_OD, dataSet[self._image_name['atoms']], dataSet[self._image_name['background']], dataSet[self._image_name['dark']], **kwargs)