darfix 4.1.1__tar.gz → 4.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. {darfix-4.1.1 → darfix-4.2.0}/LICENSE +3 -1
  2. {darfix-4.1.1/src/darfix.egg-info → darfix-4.2.0}/PKG-INFO +5 -1
  3. {darfix-4.1.1 → darfix-4.2.0}/pyproject.toml +2 -1
  4. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/_config.py +4 -1
  5. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/dataset.py +25 -44
  6. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/noiseremoval.py +13 -16
  7. darfix-4.2.0/src/darfix/core/rocking_curves.py +168 -0
  8. darfix-4.2.0/src/darfix/core/rocking_curves_map.py +45 -0
  9. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/noiseremoval/noise_removal_widget.py +36 -22
  10. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/rocking_curves/fitComboBox.py +1 -1
  11. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/rocking_curves/rockingCurvesPlot.py +17 -20
  12. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/rocking_curves/rockingCurvesWidget.py +3 -3
  13. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/math.py +53 -20
  14. darfix-4.2.0/src/darfix/processing/rocking_curves.py +408 -0
  15. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/noiseremoval.py +3 -14
  16. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/tasks/test_rocking_curves.py +1 -1
  17. darfix-4.2.0/src/darfix/tests/test_math.py +88 -0
  18. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_rocking_curves.py +8 -16
  19. {darfix-4.1.1 → darfix-4.2.0/src/darfix.egg-info}/PKG-INFO +5 -1
  20. {darfix-4.1.1 → darfix-4.2.0}/src/darfix.egg-info/SOURCES.txt +1 -0
  21. {darfix-4.1.1 → darfix-4.2.0}/src/darfix.egg-info/requires.txt +1 -0
  22. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/noiseremoval.py +1 -0
  23. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/rockingcurves.py +0 -3
  24. darfix-4.1.1/src/darfix/core/rocking_curves.py +0 -280
  25. darfix-4.1.1/src/darfix/processing/rocking_curves.py +0 -304
  26. darfix-4.1.1/src/darfix/tests/test_math.py +0 -44
  27. {darfix-4.1.1 → darfix-4.2.0}/README.md +0 -0
  28. {darfix-4.1.1 → darfix-4.2.0}/setup.cfg +0 -0
  29. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/__init__.py +0 -0
  30. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/_version.py +0 -0
  31. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/__init__.py +0 -0
  32. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/array_utils.py +0 -0
  33. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/autofocus.py +0 -0
  34. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/componentsMatching.py +0 -0
  35. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/data_selection.py +0 -0
  36. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/datapathfinder.py +0 -0
  37. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/dimension.py +0 -0
  38. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/fscan_parser.py +0 -0
  39. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/grainplot.py +0 -0
  40. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/imageRegistration.py +0 -0
  41. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/imageStack.py +0 -0
  42. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/mapping.py +0 -0
  43. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/moment_types.py +0 -0
  44. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/positioners.py +0 -0
  45. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/roi.py +0 -0
  46. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/settings.py +0 -0
  47. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/shiftcorrection.py +0 -0
  48. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/state_of_operation.py +0 -0
  49. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/transformation.py +0 -0
  50. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/utils.py +0 -0
  51. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/core/zigzag_mode.py +0 -0
  52. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/decomposition/__init__.py +0 -0
  53. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/decomposition/base.py +0 -0
  54. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/decomposition/ipca.py +0 -0
  55. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/decomposition/nica.py +0 -0
  56. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/decomposition/nmf.py +0 -0
  57. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/decomposition/pca.py +0 -0
  58. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/dtypes.py +0 -0
  59. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/PCAWidget.py +0 -0
  60. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/__init__.py +0 -0
  61. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/binningWidget.py +0 -0
  62. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/blindSourceSeparationWidget.py +0 -0
  63. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/chooseDimensions.py +0 -0
  64. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/concatenate_scans.py +0 -0
  65. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/configuration/__init__.py +0 -0
  66. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/configuration/action.py +0 -0
  67. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/configuration/level.py +0 -0
  68. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/dataPartitionWidget.py +0 -0
  69. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/data_selection/DataSelectionBase.py +0 -0
  70. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/data_selection/WorkingDirSelectionWidget.py +0 -0
  71. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/data_selection/__init__.py +0 -0
  72. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/data_selection/hdf5_data_selection_widgets.py +0 -0
  73. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/data_selection/line_edits.py +0 -0
  74. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/data_selection/scan_selection_widgets.py +0 -0
  75. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/data_selection/utils.py +0 -0
  76. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/dimensionsWidget.py +0 -0
  77. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/displayComponentsWidget.py +0 -0
  78. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/filterByDimension.py +0 -0
  79. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/grainplot/__init__.py +0 -0
  80. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/grainplot/_oridist_toolbar_buttons.py +0 -0
  81. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/grainplot/dimensionRangeSlider2D.py +0 -0
  82. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/grainplot/flashlight.py +0 -0
  83. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/grainplot/flashlight_mode_action.py +0 -0
  84. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/grainplot/grainPlotWidget.py +0 -0
  85. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/grainplot/mosaicityWidget.py +0 -0
  86. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/grainplot/oridist_toolbar.py +0 -0
  87. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/grainplot/utils.py +0 -0
  88. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/magnificationWidget.py +0 -0
  89. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/metadataWidget.py +0 -0
  90. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/noiseremoval/operation_list_widget.py +0 -0
  91. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/noiseremoval/parameters_widget.py +0 -0
  92. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/operationProcess.py +0 -0
  93. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/operationThread.py +0 -0
  94. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/projectionWidget.py +0 -0
  95. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/rocking_curves/utils.py +0 -0
  96. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/roiLimitsToolbar.py +0 -0
  97. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/roiSelectionWidget.py +0 -0
  98. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/rsmHistogramWidget.py +0 -0
  99. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/rsmWidget.py +0 -0
  100. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/shiftcorrection/__init__.py +0 -0
  101. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/shiftcorrection/shiftCorrectionWidget.py +0 -0
  102. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/shiftcorrection/shiftInput.py +0 -0
  103. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/__init__.py +0 -0
  104. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/axis_type_combobox.py +0 -0
  105. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/custom_doublespinbox.py +0 -0
  106. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/data_path_completer.py +0 -0
  107. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/data_path_selection.py +0 -0
  108. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/fileselection.py +0 -0
  109. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/message.py +0 -0
  110. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/qsignalspy.py +0 -0
  111. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/rangeSlider.py +0 -0
  112. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/standardButtonBox.py +0 -0
  113. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/utils.py +0 -0
  114. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/utils/vspacer.py +0 -0
  115. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/weakBeamWidget.py +0 -0
  116. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/gui/zSumWidget.py +0 -0
  117. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/io/__init__.py +0 -0
  118. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/io/hdf5.py +0 -0
  119. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/io/progress.py +0 -0
  120. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/io/utils.py +0 -0
  121. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/main.py +0 -0
  122. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/pixel_sizes.py +0 -0
  123. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/processing/__init__.py +0 -0
  124. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/processing/dimension_detection.py +0 -0
  125. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/processing/imageOperations.py +0 -0
  126. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/__init__.py +0 -0
  127. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/__init__.py +0 -0
  128. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/__init__.py +0 -0
  129. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/advanced_settings.png +0 -0
  130. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/advanced_settings.svg +0 -0
  131. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/contour.svg +0 -0
  132. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/curves.png +0 -0
  133. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/curves.svg +0 -0
  134. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/flashlight.svg +0 -0
  135. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/hsv.svg +0 -0
  136. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/median-filter.png +0 -0
  137. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/median-filter.svg +0 -0
  138. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/optional_settings.png +0 -0
  139. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/optional_settings.svg +0 -0
  140. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/required_settings.png +0 -0
  141. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/required_settings.svg +0 -0
  142. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/resize.png +0 -0
  143. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/resize.svg +0 -0
  144. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/scatter.png +0 -0
  145. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/gui/icons/scatter.svg +0 -0
  146. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/tests/__init__.py +0 -0
  147. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/tests/dimensions_definition/NiTi_1PD_002_g411_420MPa_mosalayers_2x.h5 +0 -0
  148. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/tests/dimensions_definition/__init__.py +0 -0
  149. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/tests/dimensions_definition/silicon_111_reflection.h5 +0 -0
  150. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/resources/tests/transformation/316H_dummy_insitu_g1_RSM_2.h5 +0 -0
  151. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/__init__.py +0 -0
  152. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/binning.py +0 -0
  153. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/blindsourceseparation.py +0 -0
  154. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/copy.py +0 -0
  155. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/datapartition.py +0 -0
  156. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/dimensiondefinition.py +0 -0
  157. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/grainplot.py +0 -0
  158. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/hdf5_data_selection.py +0 -0
  159. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/hdf5_scans_concatenation.py +0 -0
  160. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/metadata.py +0 -0
  161. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/pca.py +0 -0
  162. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/projection.py +0 -0
  163. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/rocking_curves.py +0 -0
  164. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/roi.py +0 -0
  165. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/rsm_histogram.py +0 -0
  166. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/shiftcorrection.py +0 -0
  167. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/transformation.py +0 -0
  168. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/weakbeam.py +0 -0
  169. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tasks/zsum.py +0 -0
  170. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/__init__.py +0 -0
  171. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/conftest.py +0 -0
  172. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/decomposition/__init__.py +0 -0
  173. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/decomposition/test_base.py +0 -0
  174. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/decomposition/test_ipca.py +0 -0
  175. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/decomposition/test_nica.py +0 -0
  176. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/decomposition/test_nmf.py +0 -0
  177. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/decomposition/utils.py +0 -0
  178. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/gui/test_concatenate_scans.py +0 -0
  179. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/gui/test_data_path_completer.py +0 -0
  180. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/gui/test_data_path_selection.py +0 -0
  181. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/gui/test_dimension_range_slider_2d.py +0 -0
  182. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/gui/test_range_slider_with_spinboxes.py +0 -0
  183. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/gui/test_roi_selection.py +0 -0
  184. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/orange/__init__.py +0 -0
  185. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/orange/test_ewoks.py +0 -0
  186. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/orange/widgets/__init__.py +0 -0
  187. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/orange/widgets/test_concatenate_hdf5_scans.py +0 -0
  188. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/orange/widgets/test_dimension.py +0 -0
  189. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/orange/widgets/test_hdf5_data_selection.py +0 -0
  190. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/orange/widgets/test_transformation.py +0 -0
  191. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/orange/workflow_files/concatenate_scans.ows +0 -0
  192. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/tasks/test_binning.py +0 -0
  193. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/tasks/test_data_copy.py +0 -0
  194. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/tasks/test_datapartition.py +0 -0
  195. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/tasks/test_dimensiondefinition.py +0 -0
  196. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/tasks/test_hdf5_data_selection.py +0 -0
  197. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/tasks/test_hdf5_scans_concatenation.py +0 -0
  198. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_array_utils.py +0 -0
  199. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_components_matching.py +0 -0
  200. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_datapathfinder.py +0 -0
  201. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_dataset.py +0 -0
  202. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_dimension.py +0 -0
  203. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_generate_grain_maps_nxdict.py +0 -0
  204. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_image_operations.py +0 -0
  205. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_image_registration.py +0 -0
  206. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_image_stack.py +0 -0
  207. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_mapping.py +0 -0
  208. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_mask.py +0 -0
  209. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_moments.py +0 -0
  210. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_projection.py +0 -0
  211. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_roi.py +0 -0
  212. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_rsm_histogram.py +0 -0
  213. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_save_dataset.py +0 -0
  214. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_shift.py +0 -0
  215. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_transformation.py +0 -0
  216. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_workflow.py +0 -0
  217. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_zigzag.py +0 -0
  218. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/test_zsum.py +0 -0
  219. {darfix-4.1.1 → darfix-4.2.0}/src/darfix/tests/utils.py +0 -0
  220. {darfix-4.1.1 → darfix-4.2.0}/src/darfix.egg-info/dependency_links.txt +0 -0
  221. {darfix-4.1.1 → darfix-4.2.0}/src/darfix.egg-info/entry_points.txt +0 -0
  222. {darfix-4.1.1 → darfix-4.2.0}/src/darfix.egg-info/top_level.txt +0 -0
  223. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/__init__.py +0 -0
  224. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/tutorials/__init__.py +0 -0
  225. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/tutorials/darfix_example1.ows +0 -0
  226. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/tutorials/darfix_example_hdf.ows +0 -0
  227. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/tutorials/edf_dataset/strain_0000.edf +0 -0
  228. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/tutorials/edf_dataset/strain_0001.edf +0 -0
  229. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/tutorials/hdf5_dataset/strain.hdf5 +0 -0
  230. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/tutorials/tutorial_workflow.ows +0 -0
  231. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/__init__.py +0 -0
  232. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/binning.py +0 -0
  233. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/blindsourceseparation.py +0 -0
  234. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/concatenateHDF5.py +0 -0
  235. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/datacopy.py +0 -0
  236. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/datapartition.py +0 -0
  237. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/datasetWidgetBase.py +0 -0
  238. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/dimensions.py +0 -0
  239. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/grainplot.py +0 -0
  240. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/hdf5dataselection.py +0 -0
  241. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/__init__.py +0 -0
  242. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/axes.png +0 -0
  243. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/axes.svg +0 -0
  244. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/bss.png +0 -0
  245. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/bss.svg +0 -0
  246. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/category.svg +0 -0
  247. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/concatenate_hdf5.svg +0 -0
  248. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/copy.svg +0 -0
  249. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/curves.png +0 -0
  250. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/curves.svg +0 -0
  251. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/darfix_icon.png +0 -0
  252. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/darfix_icon.svg +0 -0
  253. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/darfix_icon8.png +0 -0
  254. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/filter.png +0 -0
  255. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/filter.svg +0 -0
  256. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/gaussian.png +0 -0
  257. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/gaussian.svg +0 -0
  258. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/grainplot.png +0 -0
  259. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/grainplot.svg +0 -0
  260. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/image-select-box.svg +0 -0
  261. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/metadata.png +0 -0
  262. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/metadata.svg +0 -0
  263. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/mywidget.svg +0 -0
  264. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/noise_removal.png +0 -0
  265. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/noise_removal.svg +0 -0
  266. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/noise_removal_backup.svg +0 -0
  267. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/param_dims.png +0 -0
  268. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/param_dims.svg +0 -0
  269. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/pca.png +0 -0
  270. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/pca.svg +0 -0
  271. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/random.svg +0 -0
  272. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/resize.png +0 -0
  273. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/roi.png +0 -0
  274. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/roi.svg +0 -0
  275. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/save.svg +0 -0
  276. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/shift_correction.svg +0 -0
  277. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/upload_edf.svg +0 -0
  278. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/upload_hdf5.svg +0 -0
  279. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/icons/zsum.svg +0 -0
  280. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/metadata.py +0 -0
  281. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/operationWidgetBase.py +0 -0
  282. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/pca.py +0 -0
  283. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/projection.py +0 -0
  284. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/roiselection.py +0 -0
  285. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/rsmhistogram.py +0 -0
  286. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/shiftcorrection.py +0 -0
  287. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/transformation.py +0 -0
  288. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/weakbeam.py +0 -0
  289. {darfix-4.1.1 → darfix-4.2.0}/src/orangecontrib/darfix/widgets/zsum.py +0 -0
@@ -18,4 +18,6 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
22
+
23
+ This project uses joblib (https://github.com/joblib/joblib), licensed under the BSD 3-Clause License.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: darfix
3
- Version: 4.1.1
3
+ Version: 4.2.0
4
4
  Summary: Computer vision software for the interpretation of diffraction images
5
5
  Author-email: ESRF <dau-pydev@esrf.fr>
6
6
  License: The MIT license follows:
@@ -24,6 +24,9 @@ License: The MIT license follows:
24
24
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
25
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
26
  SOFTWARE.
27
+
28
+ This project uses joblib (https://github.com/joblib/joblib), licensed under the BSD 3-Clause License.
29
+
27
30
  Project-URL: Homepage, https://gitlab.esrf.fr/XRD/darfix/
28
31
  Project-URL: Documentation, http://www.edna-site.org/pub/doc/darfix/latest
29
32
  Project-URL: Repository, https://gitlab.esrf.fr/XRD/darfix/
@@ -46,6 +49,7 @@ Requires-Dist: packaging
46
49
  Requires-Dist: scikit-learn
47
50
  Requires-Dist: scipy
48
51
  Requires-Dist: tqdm
52
+ Requires-Dist: joblib
49
53
  Requires-Dist: eval_type_backport
50
54
  Provides-Extra: full-noqt
51
55
  Requires-Dist: opencv-python-headless>=4.3.0.36; extra == "full-noqt"
@@ -8,7 +8,7 @@ addopts = "--import-mode=importlib" # for all pytest versions, pytest-cov needs
8
8
 
9
9
  [project]
10
10
  name = "darfix"
11
- version = "4.1.1"
11
+ version = "4.2.0"
12
12
  keywords = ["orange3 add-on","ewoks"]
13
13
  authors = [{name = "ESRF", email = "dau-pydev@esrf.fr"}]
14
14
  description = "Computer vision software for the interpretation of diffraction images"
@@ -31,6 +31,7 @@ dependencies = [
31
31
  "scikit-learn",
32
32
  "scipy",
33
33
  "tqdm",
34
+ "joblib",
34
35
  "eval_type_backport"
35
36
  ]
36
37
 
@@ -1,3 +1,6 @@
1
+ FWHM_VAL = 2.35482 # For numba
2
+
3
+
1
4
  class Config:
2
5
  """
3
6
  Class containing shared global configuration for the darfix project.
@@ -15,7 +18,7 @@ class Config:
15
18
  .. versionadded:: 0.3
16
19
  """
17
20
 
18
- FWHM_VAL = 2.35482
21
+ FWHM_VAL = FWHM_VAL
19
22
 
20
23
  """Magic value that returns FWHM when multiplied by the standard deviation.
21
24
 
@@ -30,9 +30,7 @@ from darfix.core.mapping import compute_magnification
30
30
  from darfix.core.mapping import compute_moments
31
31
  from darfix.core.mapping import compute_rsm
32
32
  from darfix.core.positioners import Positioners
33
- from darfix.core.rocking_curves import fit_1d_data
34
- from darfix.core.rocking_curves import fit_2d_data
35
- from darfix.core.rocking_curves import fit_3d_data
33
+ from darfix.core.rocking_curves import fit_rocking_curve_parallel
36
34
  from darfix.core.roi import apply_2D_ROI
37
35
  from darfix.core.roi import apply_3D_ROI
38
36
  from darfix.core.state_of_operation import Operation
@@ -729,61 +727,44 @@ class ImageDataset(ImageStack):
729
727
  """
730
728
  if not self.dims.ndim:
731
729
  raise NoDimensionsError("apply_fit")
730
+ if indices is None:
731
+ indices = Ellipsis
732
732
 
733
733
  new_dataset = self.copy(new_data=self.data.copy())
734
734
 
735
735
  with self.state_of_operations.run_context(Operation.FIT):
736
- data = new_dataset.as_array3d(indices)
736
+ data = new_dataset.as_array3d()
737
737
  # Fit can only be done if rocking curves are at least of size 3
738
- if len(data) < 3:
738
+ if len(self.data) < 3:
739
739
  raise ValueError(
740
- f"Fit can only be done if rocking curves are at least of dimensionality 3. Got {len(data)}"
740
+ f"Fit can only be done if dataset has not at least 3 dimensions. Got {len(data)}"
741
741
  )
742
742
 
743
743
  if self.dims.ndim == 1:
744
744
  dim0 = self.dims.get(0)
745
- data[:], maps = fit_1d_data(
746
- data=data,
747
- values=self.get_metadata_values(dim0.name, indices),
748
- int_thresh=int_thresh,
749
- method=method,
750
- )
751
- elif self.dims.ndim == 2:
752
- # TODO: `indices` seem to be handled differently here ??
753
- dim0 = self.dims.get(0)
754
- dim1 = self.dims.get(1)
755
- values = [
756
- self.get_metadata_values(key=dim0.name),
757
- self.get_metadata_values(key=dim1.name),
745
+ motor_values = self.metadata_dict[dim0.name].ravel()[indices]
746
+ elif self.dims.ndim <= 3:
747
+
748
+ ndim = self.dims.ndim
749
+ dimension_names = [
750
+ self.dims.get(dim_idx).name for dim_idx in range(ndim)
758
751
  ]
759
- data[:], maps = fit_2d_data(
760
- data=self.as_array3d(),
761
- values=values,
762
- shape=(dim0.size, dim1.size),
763
- int_thresh=int_thresh,
764
- indices=indices,
765
- method=method,
766
- )
767
- elif self.dims.ndim == 3:
768
- # TODO: `indices` seem to be handled differently here ??
769
- dim0 = self.dims.get(0)
770
- dim1 = self.dims.get(1)
771
- dim2 = self.dims.get(2)
772
- data[:], maps = fit_3d_data(
773
- data=self.as_array3d(),
774
- motor_values=[
775
- self.get_metadata_values(key=dim0.name),
776
- self.get_metadata_values(key=dim1.name),
777
- self.get_metadata_values(key=dim2.name),
778
- ],
779
- shape=(dim0.size, dim1.size, dim2.size),
780
- int_thresh=int_thresh,
781
- indices=indices,
782
- method=method,
783
- )
752
+
753
+ motor_values = [
754
+ self.metadata_dict[dim_name].ravel()[indices]
755
+ for dim_name in dimension_names
756
+ ]
757
+
784
758
  else:
785
759
  raise TooManyDimensionsForRockingCurvesError()
786
760
 
761
+ data[indices], maps = fit_rocking_curve_parallel(
762
+ data=self.as_array3d(indices),
763
+ motor_values=motor_values,
764
+ thresh=int_thresh,
765
+ method=method,
766
+ )
767
+
787
768
  return (
788
769
  new_dataset,
789
770
  maps,
@@ -71,36 +71,33 @@ def apply_noise_removal_operation(
71
71
  apply_mask_removal(image, **operation["parameters"])
72
72
 
73
73
 
74
- def create_background_substraction_operation(
74
+ def add_background_data_into_operation(
75
75
  dataset: Dataset,
76
- method: str | None = None,
77
- background_type: BackgroundType | None = None,
76
+ operation: NoiseRemovalOperation,
78
77
  ) -> NoiseRemovalOperation:
79
78
  """Compute a background image and return a NoiseRemovalOperation with a background parameter"""
80
79
 
81
- if method is None:
82
- method = imageOperations.Method.MEDIAN
80
+ if operation["type"] is not Operation.BS:
81
+ raise ValueError("Operation type should be `Operation.BS`")
83
82
 
84
- if background_type is not None:
85
- background_type = BackgroundType(background_type)
83
+ method = operation["parameters"].get("method", imageOperations.Method.MEDIAN)
86
84
 
87
- if background_type == BackgroundType.DARK_DATA:
85
+ background_type = BackgroundType(
86
+ operation["parameters"].get("background_type", BackgroundType.DATA.value)
87
+ )
88
+
89
+ if background_type is BackgroundType.DARK_DATA:
88
90
  bg = dataset.bg_dataset.as_array3d()
89
- elif background_type == BackgroundType.UNUSED_DATA:
91
+ elif background_type is BackgroundType.UNUSED_DATA:
90
92
  bg = dataset.dataset.as_array3d(dataset.bg_indices)
91
- elif background_type == BackgroundType.DATA:
93
+ elif background_type is BackgroundType.DATA:
92
94
  bg = dataset.dataset.as_array3d()
93
95
  else:
94
96
  raise NotImplementedError(
95
97
  f"Background type {background_type!r} not implemented yet."
96
98
  )
97
- parameters = dict(method=method, background_type=background_type)
98
99
 
99
- return NoiseRemovalOperation(
100
- type=Operation.BS,
101
- parameters=parameters,
102
- background=imageOperations.compute_background(bg, method),
103
- )
100
+ operation["background"] = imageOperations.compute_background(bg, method)
104
101
 
105
102
 
106
103
  def apply_background_substraction(
@@ -0,0 +1,168 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Sequence
4
+
5
+ import numpy
6
+ import tqdm
7
+ from joblib import Parallel
8
+ from joblib import delayed
9
+
10
+ from ..io.utils import create_nxdata_dict
11
+ from ..processing.rocking_curves import FitMethod
12
+ from ..processing.rocking_curves import fit_1d_rocking_curve
13
+ from ..processing.rocking_curves import fit_2d_rocking_curve
14
+ from ..processing.rocking_curves import fit_3d_rocking_curve
15
+ from .rocking_curves_map import MAPS_1D
16
+ from .rocking_curves_map import MAPS_2D
17
+ from .rocking_curves_map import MAPS_3D
18
+ from .rocking_curves_map import Maps_1D
19
+ from .utils import NoDimensionsError
20
+ from .utils import TooManyDimensionsForRockingCurvesError
21
+
22
+
23
+ def _rocking_curves_per_px(data: numpy.ndarray):
24
+ """
25
+ Generator that returns the rocking curve for every pixel
26
+
27
+ :param ndarray data: data to analyse
28
+ """
29
+ for j in range(data.shape[1]):
30
+ for i in range(data.shape[2]):
31
+ yield data[:, j, i]
32
+
33
+
34
+ def _wrap_fit_function(fit_function, motor_values, thresh, method, curve_per_px):
35
+ """
36
+ Just a wrapper to pack the result of the fit.
37
+
38
+ See `_fit_xd_data` for parameters details and typing
39
+ """
40
+
41
+ y_gauss, fit_result = fit_function(curve_per_px, motor_values, method, thresh)
42
+
43
+ return y_gauss, fit_result
44
+
45
+
46
+ def fit_rocking_curve_parallel(
47
+ data: numpy.ndarray,
48
+ motor_values: Sequence[numpy.ndarray] | numpy.ndarray,
49
+ thresh: float | None,
50
+ method: FitMethod | None,
51
+ ) -> tuple[numpy.ndarray, numpy.ndarray]:
52
+ """
53
+ Fit the rocking curves using multiprocessing.
54
+
55
+ :param data: 3D data [N frames, height, width] array to fit.
56
+ :param motor_values: x values associated to axis 0 of the 3D data. Can be 2D [dims count, N frames] or 1D [N frames]
57
+ :param thresh: Optional threshold value for each rocking curve. If Peak-to-peak value is nelow this threshold, data is not fitted.
58
+ :param method: Method to use in `scipy.optimize.curve_fit`.
59
+
60
+ :return:
61
+ - Fitted 3D data array [N frames, height, width]
62
+ - A [len_maps, height, width] 3D array of the fit parameters.
63
+ """
64
+
65
+ motor_values = numpy.asarray(motor_values, numpy.float64)
66
+ height, width = data.shape[-2:]
67
+
68
+ if motor_values.ndim == 1:
69
+ fit_function = fit_1d_rocking_curve
70
+ len_maps = len(MAPS_1D)
71
+ elif motor_values.ndim == 2 and motor_values.shape[0] == 2:
72
+ fit_function = fit_2d_rocking_curve
73
+ len_maps = len(MAPS_2D)
74
+ elif motor_values.ndim == 2 and motor_values.shape[0] == 3:
75
+ fit_function = fit_3d_rocking_curve
76
+ len_maps = len(MAPS_3D)
77
+ else:
78
+ raise ValueError(f"motor_values has a bad shape : {motor_values.shape}")
79
+
80
+ output_data = numpy.zeros_like(data)
81
+ maps = numpy.full((len_maps,) + data.shape[-2:], numpy.nan)
82
+
83
+ with Parallel(n_jobs=-1, return_as="generator") as parallel_processing:
84
+ results = parallel_processing(
85
+ delayed(_wrap_fit_function)(
86
+ fit_function, motor_values, thresh, method, curve
87
+ )
88
+ for curve in _rocking_curves_per_px(data)
89
+ )
90
+
91
+ for idx, (y_gauss, maps_ji) in tqdm.tqdm(
92
+ enumerate(results), desc="Fit rocking curves", total=height * width
93
+ ):
94
+ j = idx // data.shape[2]
95
+ i = idx % data.shape[2]
96
+ output_data[:, j, i] = y_gauss
97
+ maps[:, j, i] = maps_ji
98
+
99
+ return output_data, maps
100
+
101
+
102
+ def generate_rocking_curves_nxdict(
103
+ dataset, # ImageDataset. Cannot type due to circular import
104
+ maps: numpy.ndarray,
105
+ residuals: numpy.ndarray | None,
106
+ ) -> dict:
107
+ if not dataset.dims.ndim:
108
+ raise NoDimensionsError("generate_rocking_curves_nxdict")
109
+ entry = "entry"
110
+
111
+ nx = {
112
+ entry: {"@NX_class": "NXentry"},
113
+ "@NX_class": "NXroot",
114
+ "@default": entry,
115
+ }
116
+
117
+ if dataset.transformation:
118
+ axes = [
119
+ dataset.transformation.yregular,
120
+ dataset.transformation.xregular,
121
+ ]
122
+ axes_names = ["y", "x"]
123
+ axes_long_names = [
124
+ dataset.transformation.label,
125
+ dataset.transformation.label,
126
+ ]
127
+ else:
128
+ axes = None
129
+ axes_names = None
130
+ axes_long_names = None
131
+
132
+ if dataset.dims.ndim == 1:
133
+ map_names = MAPS_1D
134
+ elif dataset.dims.ndim == 2:
135
+ map_names = MAPS_2D
136
+ elif dataset.dims.ndim == 3:
137
+ map_names = MAPS_3D
138
+ else:
139
+ raise TooManyDimensionsForRockingCurvesError()
140
+
141
+ for i, map_name in enumerate(map_names):
142
+ signal = maps[i]
143
+ nx[entry][map_name] = create_nxdata_dict(
144
+ signal, map_name, axes, axes_names, axes_long_names
145
+ )
146
+ if residuals is not None:
147
+ nx[entry]["Residuals"] = create_nxdata_dict(
148
+ residuals, "Residuals", axes, axes_names, axes_long_names
149
+ )
150
+ nx[entry]["@default"] = Maps_1D.AMPLITUDE.value
151
+
152
+ return nx
153
+
154
+
155
+ def compute_residuals(
156
+ target_dataset, # ImageDataset. Cannot type due to circular import
157
+ original_dataset, # ImageDataset. Cannot type due to circular import
158
+ indices: numpy.ndarray | None,
159
+ ):
160
+ return numpy.sqrt(
161
+ (
162
+ numpy.subtract(
163
+ target_dataset.as_array3d(indices),
164
+ original_dataset.as_array3d(indices),
165
+ )
166
+ ** 2
167
+ ).sum(axis=(0))
168
+ )
@@ -0,0 +1,45 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import Enum as _Enum
4
+
5
+
6
+ class Maps_1D(_Enum):
7
+ """Names of the fitting parameters of the 1D fit result. Each result is a map of frame size."""
8
+
9
+ AMPLITUDE = "Amplitude"
10
+ FWHM = "FWHM"
11
+ PEAK = "Peak position"
12
+ BACKGROUND = "Background"
13
+
14
+
15
+ class Maps_2D(_Enum):
16
+ """Names of the fitting parameters of the 2D fit result. Each result is a map of frame size."""
17
+
18
+ PEAK_X = "Peak position first motor"
19
+ PEAK_Y = "Peak position second motor"
20
+ FWHM_X = "FWHM first motor"
21
+ FWHM_Y = "FWHM second motor"
22
+ AMPLITUDE = "Amplitude"
23
+ CORRELATION = "Correlation"
24
+ BACKGROUND = "Background"
25
+
26
+
27
+ class Maps_3D(_Enum):
28
+ """Names of the fitting parameters of the 3D fit result. Each result is a map of frame size."""
29
+
30
+ PEAK_X = "Peak position first motor"
31
+ PEAK_Y = "Peak position second motor"
32
+ PEAK_Z = "Peak position third motor"
33
+ FWHM_X = "FWHM first motor"
34
+ FWHM_Y = "FWHM second motor"
35
+ FWHM_Z = "FWHM third motor"
36
+ CORRELATION_XY = "Cross-correlation between first and second motors"
37
+ CORRELATION_XZ = "Cross-correlation between first and third motors"
38
+ CORRELATION_YZ = "Cross-correlation between second and third motors"
39
+ AMPLITUDE = "Amplitude"
40
+ BACKGROUND = "Background"
41
+
42
+
43
+ MAPS_1D: tuple[Maps_1D] = tuple(member.value for member in Maps_1D)
44
+ MAPS_2D: tuple[Maps_2D] = tuple(member.value for member in Maps_2D)
45
+ MAPS_3D: tuple[Maps_3D] = tuple(member.value for member in Maps_3D)
@@ -13,8 +13,9 @@ from darfix import config
13
13
  from darfix import dtypes
14
14
  from darfix.core.noiseremoval import BackgroundType
15
15
  from darfix.core.noiseremoval import NoiseRemovalOperation
16
+ from darfix.core.noiseremoval import add_background_data_into_operation
16
17
  from darfix.core.noiseremoval import apply_noise_removal_operation
17
- from darfix.core.noiseremoval import create_background_substraction_operation
18
+ from darfix.core.noiseremoval import operation_to_str
18
19
  from darfix.core.state_of_operation import Operation
19
20
  from darfix.gui.operationThread import OperationThread
20
21
 
@@ -132,10 +133,10 @@ class NoiseRemovalWidget(qt.QWidget):
132
133
  def setDataset(self, dataset: dtypes.Dataset):
133
134
  """Saves the dataset and updates the stack with the dataset data."""
134
135
 
135
- self._operationList.clear()
136
136
  self._plot.clear()
137
137
 
138
138
  self._dataset = dataset
139
+
139
140
  if self._imgDataset.title != "":
140
141
  self._plot.setTitleCallback(lambda idx: self._imgDataset.title)
141
142
 
@@ -163,30 +164,50 @@ class NoiseRemovalWidget(qt.QWidget):
163
164
  )
164
165
  self._parametersWidget.bsBackgroundCB.addItem(BackgroundType.DATA.value)
165
166
 
167
+ opersations = self._operationList.getOperations()
168
+
169
+ if (
170
+ len(opersations) > 0
171
+ and qt.QMessageBox.question(
172
+ self,
173
+ "Keep operation list ?",
174
+ "Do you want to restore these operations ?\n\n - "
175
+ + "\n - ".join([operation_to_str(op) for op in opersations]),
176
+ )
177
+ == qt.QMessageBox.StandardButton.Yes
178
+ ):
179
+ for operation in opersations:
180
+ if operation["type"] is Operation.BS:
181
+ self._computeBackgroundAsync(operation)
182
+ else:
183
+ self._operationList.clear()
184
+
166
185
  def _launchBackgroundSubtraction(self):
167
- self._computeBackgroundAsync(
168
- self._parametersWidget.bsBackgroundCB.currentText(),
169
- self._parametersWidget.bsMethodsCB.currentText(),
186
+ operation = NoiseRemovalOperation(
187
+ type=Operation.BS,
188
+ parameters={
189
+ "method": self._parametersWidget.bsMethodsCB.currentText(),
190
+ "background_type": self._parametersWidget.bsBackgroundCB.currentText(),
191
+ },
170
192
  )
193
+ self._operationList.append(operation)
194
+ self._computeBackgroundAsync(operation)
171
195
 
172
- def _computeBackgroundAsync(self, background_type: str, method: str):
196
+ def _computeBackgroundAsync(self, operation: NoiseRemovalOperation):
173
197
 
174
198
  assert (
175
199
  self._backgroundComputationThread is None
176
200
  ), "Computation thread is expected to be None."
177
201
 
178
202
  self._parametersWidget.setDisabled(True)
203
+ self._browser.setDisabled(True)
179
204
  self._parametersWidget.computeBS.setWaiting(True)
180
205
 
181
- # Here the background image is computed.
206
+ # Here the background image data is computed.
182
207
  self._backgroundComputationThread = OperationThread(
183
- self, create_background_substraction_operation
184
- )
185
- self._backgroundComputationThread.setArgs(
186
- self._dataset,
187
- method,
188
- background_type,
208
+ self, add_background_data_into_operation
189
209
  )
210
+ self._backgroundComputationThread.setArgs(self._dataset, operation)
190
211
  self._backgroundComputationThread.finished.connect(
191
212
  self._onBackgroundComputationFinish
192
213
  )
@@ -194,19 +215,12 @@ class NoiseRemovalWidget(qt.QWidget):
194
215
 
195
216
  def _onBackgroundComputationFinish(self):
196
217
  self._parametersWidget.setEnabled(True)
218
+ self._browser.setEnabled(True)
197
219
  self._parametersWidget.computeBS.setWaiting(False)
198
220
 
199
- if self._backgroundComputationThread.data is None:
200
- raise RuntimeError("An exception occured during background computation.")
201
-
202
- # Result of `create_background_substraction_operation` is a new operation that contains the pre-computed 2D background image
203
- operation = self._backgroundComputationThread.data
204
-
205
221
  self._backgroundComputationThread = None
206
222
 
207
- if operation is not None:
208
- self._operationList.append(operation)
209
- self.refreshPlot()
223
+ self.refreshPlot()
210
224
 
211
225
  def _launchHotPixelRemoval(self):
212
226
  size = self._parametersWidget.hpSizeCB.currentText()
@@ -18,4 +18,4 @@ class FitComboBox(qt.QComboBox):
18
18
  "Unbounded Levenberg-Marquardt algorithm as implemented in MINPACK. Doesn’t handle bounds and sparse Jacobians. Usually the most efficient method for small unconstrained problems.",
19
19
  )
20
20
 
21
- self.setCurrentText("lm")
21
+ self.setCurrentText("trf") # The most stable
@@ -234,28 +234,27 @@ class RockingCurvesPlot(qt.QWidget):
234
234
  origin = self._computeFitPlotOrigin(dim1, dim0)
235
235
  scale = self._computeFitPlotScale(dim1, dim0)
236
236
  self._fitPlot.remove(kind="curve")
237
+ x_values = numpy.stack(
238
+ [
239
+ dataset.get_metadata_values(key=dim0.name),
240
+ dataset.get_metadata_values(key=dim1.name),
241
+ ]
242
+ )
243
+
237
244
  try:
238
- y_gauss, pars = fit_2d_rocking_curve(
239
- (y_values, None),
240
- x_values=[
241
- dataset.get_metadata_values(key=dim0.name),
242
- dataset.get_metadata_values(key=dim1.name),
243
- ],
244
- shape=(dim0.size, dim1.size),
245
- )
246
- if numpy.array_equal(y_gauss, y_values):
247
- raise RuntimeError()
248
- y_gauss = numpy.reshape(y_gauss, (dim1.size, dim0.size)).T
245
+ y_gauss, pars = fit_2d_rocking_curve(rocking_curve, x_values)
249
246
 
250
247
  except (TypeError, RuntimeError):
251
- _logger.warning("Cannot fit")
248
+ _logger.warning("Cannot fit", exc_info=True)
249
+ y_gauss = numpy.full_like(rocking_curve, numpy.nan)
252
250
  else:
253
251
  self._lastFitParamsLabel.setText(
254
252
  "PEAK_X:{:.3f} PEAK_Y:{:.3f} FWHM_X:{:.3f} FWHM_Y:{:.3f} AMP:{:.3f} CORR:{:.3f} BG:{:.3f}".format(
255
253
  *pars
256
254
  )
257
255
  )
258
- image = numpy.reshape(y_values, (dim1.size, dim0.size)).T
256
+ image = numpy.reshape(rocking_curve, (dim1.size, dim0.size)).T
257
+ fit_image = numpy.reshape(y_gauss, (dim1.size, dim0.size)).T
259
258
  self._fitPlot.addImage(
260
259
  image,
261
260
  xlabel=dim1.name,
@@ -264,7 +263,7 @@ class RockingCurvesPlot(qt.QWidget):
264
263
  scale=scale,
265
264
  legend=FIT_IMAGE_LEGEND,
266
265
  )
267
- contours = compute_contours(image)
266
+ contours = compute_contours(fit_image)
268
267
  self._addFitContours(contours)
269
268
 
270
269
  frameNumber = self._sv.getFrameNumber()
@@ -289,15 +288,13 @@ class RockingCurvesPlot(qt.QWidget):
289
288
  self._fitPlot.setGraphYLabel("Intensity")
290
289
  i = self._sv.getFrameNumber()
291
290
  try:
292
- y_gauss, pars = fit_1d_rocking_curve(
293
- (numpy.array(rocking_curve), None), x_values=x, num_points=1000
294
- )
291
+ y_gauss, pars = fit_1d_rocking_curve(rocking_curve, x)
295
292
  self._lastFitParamsLabel.setText(
296
293
  "AMP:{:.3f} PEAK:{:.3f} FWHM:{:.3f} BG:{:.3f}".format(*pars)
297
294
  )
298
- except TypeError:
299
- y_gauss = rocking_curve
300
- _logger.warning("Cannot fit")
295
+ except (TypeError, RuntimeError):
296
+ _logger.warning("Cannot fit", exc_info=True)
297
+ y_gauss = numpy.full_like(rocking_curve, numpy.nan)
301
298
  else:
302
299
  x_gauss = numpy.linspace(x[0], x[-1], len(y_gauss))
303
300
  self._fitPlot.addCurve(x_gauss, y_gauss, legend="fit", color="r")
@@ -9,10 +9,10 @@ from silx.io.dictdump import dicttonx
9
9
 
10
10
  from ... import dtypes
11
11
  from ...core.dataset import Operation
12
- from ...core.rocking_curves import MAPS_1D
13
- from ...core.rocking_curves import MAPS_2D
14
- from ...core.rocking_curves import MAPS_3D
15
12
  from ...core.rocking_curves import generate_rocking_curves_nxdict
13
+ from ...core.rocking_curves_map import MAPS_1D
14
+ from ...core.rocking_curves_map import MAPS_2D
15
+ from ...core.rocking_curves_map import MAPS_3D
16
16
  from ...core.utils import NoDimensionsError
17
17
  from ...core.utils import TooManyDimensionsForRockingCurvesError
18
18
  from ..utils.message import missing_dataset_msg