qcodespp 0.1.3__tar.gz → 0.1.4__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 (85) hide show
  1. {qcodespp-0.1.3 → qcodespp-0.1.4}/PKG-INFO +1 -1
  2. {qcodespp-0.1.3 → qcodespp-0.1.4}/pyproject.toml +1 -1
  3. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/__init__.py +1 -0
  4. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/analysis_tools.py +8 -5
  5. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/datatypes.py +7 -4
  6. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/editor.py +23 -8
  7. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/filters.py +138 -27
  8. qcodespp-0.1.4/qcodespp/version.py +1 -0
  9. qcodespp-0.1.3/qcodespp/version.py +0 -1
  10. {qcodespp-0.1.3 → qcodespp-0.1.4}/LICENSE +0 -0
  11. {qcodespp-0.1.3 → qcodespp-0.1.4}/README.rst +0 -0
  12. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/actions.py +0 -0
  13. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/data/__init__.py +0 -0
  14. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/data/data_array.py +0 -0
  15. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/data/data_set.py +0 -0
  16. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/data/format.py +0 -0
  17. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/data/gnuplot_format.py +0 -0
  18. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/data/hdf5_format.py +0 -0
  19. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/data/hdf5_format_hickle.py +0 -0
  20. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/data/io.py +0 -0
  21. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/data/location.py +0 -0
  22. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/Keysight/Keysight_34450A.py +0 -0
  23. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/Keysight/__init__.py +0 -0
  24. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/Keysight/private/Keysight_344xxA.py +0 -0
  25. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/Keysight/private/__init__.py +0 -0
  26. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/Lakeshore/Model_340.py +0 -0
  27. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/Lakeshore/__init__.py +0 -0
  28. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/QDevil/159fit_params_high_latest.json +0 -0
  29. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/QDevil/159fit_params_low_latest.json +0 -0
  30. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/QDevil/71fit_params_high_latest.json +0 -0
  31. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/QDevil/71fit_params_low_latest.json +0 -0
  32. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/QDevil/QDAC2.py +0 -0
  33. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/QDevil/QDAC2_Array.py +0 -0
  34. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/QDevil/QSwitch_elab.py +0 -0
  35. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/QDevil/__init__.py +0 -0
  36. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/ZI/ZIHF2LI.py +0 -0
  37. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/ZI/ZIMFLI.py +0 -0
  38. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/ZI/ZIMFLI_sync.py +0 -0
  39. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/ZI/__init__.py +0 -0
  40. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/__init__.py +0 -0
  41. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/cryogenic/CryogenicSMS120C.py +0 -0
  42. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/cryogenic/__init__.py +0 -0
  43. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/instrument_mocks.py +0 -0
  44. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/multiplexer_instrument.py +0 -0
  45. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/national_instruments/PXI_4461.py +0 -0
  46. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/national_instruments/PXI_4462.py +0 -0
  47. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/national_instruments/PXI_6259.py +0 -0
  48. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/national_instruments/PXI_6733.py +0 -0
  49. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/national_instruments/PXI_6733_e.py +0 -0
  50. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/national_instruments/__init__.py +0 -0
  51. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/oxford/__init__.py +0 -0
  52. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/oxford/mercuryiPS_serial.py +0 -0
  53. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/oxford/serial.py +0 -0
  54. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/oxford/triton.py +0 -0
  55. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/tektronix/Keithley_2000_Scan.py +0 -0
  56. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/tektronix/Keithley_2182a.py +0 -0
  57. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/tektronix/Keithley_2450.py +0 -0
  58. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/tektronix/Keithley_2700.py +0 -0
  59. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/tektronix/__init__.py +0 -0
  60. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/wir/Kepco.py +0 -0
  61. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/wir/__init__.py +0 -0
  62. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/yokogawa/GS200.py +0 -0
  63. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/instrument_drivers/yokogawa/__init__.py +0 -0
  64. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/loops.py +0 -0
  65. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/measure.py +0 -0
  66. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/parameters.py +0 -0
  67. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/RemotePlot.py +0 -0
  68. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/RemotePlotClient.py +0 -0
  69. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/RemoteQtPlotWidgets.py +0 -0
  70. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/__init__.py +0 -0
  71. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/colors.py +0 -0
  72. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/__init__.py +0 -0
  73. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/design.py +0 -0
  74. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/design.ui +0 -0
  75. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/fits.py +0 -0
  76. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/helpers.py +0 -0
  77. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/iconGadget.png +0 -0
  78. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/main.py +0 -0
  79. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/popupwindows.py +0 -0
  80. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/qcodes_pp_extension.py +0 -0
  81. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/plotting/offline/sidebars.py +0 -0
  82. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/station.py +0 -0
  83. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/utils/__init__.py +0 -0
  84. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/utils/helpers.py +0 -0
  85. {qcodespp-0.1.3 → qcodespp-0.1.4}/qcodespp/utils/visa_helpers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qcodespp
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Package providing additional functions for QCoDeS
5
5
  Maintainer-email: Damon Carrad <damonc@dtu.dk>
6
6
  Requires-Python: >=3.10
@@ -5,7 +5,7 @@ build-backend = 'flit_core.buildapi'
5
5
 
6
6
  [project]
7
7
  name = "qcodespp"
8
- version = '0.1.3'
8
+ version = '0.1.4'
9
9
  maintainers = [{name = "Damon Carrad", email = "damonc@dtu.dk"}]
10
10
  description = "Package providing additional functions for QCoDeS"
11
11
  classifiers = [
@@ -65,6 +65,7 @@ from qcodespp.actions import Task, Wait, BreakIf
65
65
 
66
66
  from qcodespp.plotting.RemotePlot import Plot, live_plot
67
67
  from qcodespp.plotting.offline.main import offline_plotting
68
+ from qcodespp.plotting.analysis_tools import colorplot, colored_traces
68
69
 
69
70
  from qcodespp.data.data_set import new_data, load_data, load_data_num, load_data_nums, set_data_format, set_data_folder
70
71
 
@@ -7,7 +7,8 @@ from matplotlib.ticker import MultipleLocator
7
7
  import numpy as np
8
8
 
9
9
 
10
- def colorplot(x,y,z,figsize=0,cmap=0,labels=0,xlim=0,ylim=0,zlim=0,xmajor=0,xminor=0,ymajor=0,yminor=0,font_size=0,label_size=0):
10
+ def colorplot(x,y,z,figsize=0,cmap=0,labels=0,xlim=0,ylim=0,zlim=0,xmajor=0,
11
+ xminor=0,ymajor=0,yminor=0,font_size=0,label_size=0,check_shapes=True):
11
12
  """
12
13
  Make a nice colourplot from a three-dimensional data array using matplotlib.
13
14
 
@@ -43,6 +44,7 @@ def colorplot(x,y,z,figsize=0,cmap=0,labels=0,xlim=0,ylim=0,zlim=0,xmajor=0,xmin
43
44
 
44
45
  label_size (int, optional): Font size for the tick labels. Default is 12.
45
46
 
47
+ check_shapes (bool, optional): If True, checks the shapes of x, y, and z arrays and transposes if necessary. Default is True.
46
48
 
47
49
  Returns:
48
50
  tuple: A tuple containing the figure, axis, and colorbar axis objects.
@@ -65,10 +67,11 @@ def colorplot(x,y,z,figsize=0,cmap=0,labels=0,xlim=0,ylim=0,zlim=0,xmajor=0,xmin
65
67
  fig, (ax1, cax)=plt.subplots(nrows=1,ncols=2,figsize=figsize,dpi=300,gridspec_kw={'width_ratios':[1,0.02]}) #This allows us better control over the colourbar. Note you can then 'easily' generalise this to more subplots (see below)
66
68
  fig.tight_layout(h_pad=None, w_pad=-2)
67
69
 
68
- if np.shape(z)[1] != np.shape(x)[0] and np.shape(z)[0] == np.shape(x)[0]:
69
- z= z.T
70
- if np.shape(np.shape(y))==(2,) and np.shape(y)[1] != np.shape(x)[0] and np.shape(y)[0] == np.shape(x)[0]:
71
- y= y.T
70
+ if check_shapes:
71
+ if np.shape(z)[1] != np.shape(x)[0] and np.shape(z)[0] == np.shape(x)[0]:
72
+ z= z.T
73
+ if np.shape(np.shape(y))==(2,) and np.shape(y)[1] != np.shape(x)[0] and np.shape(y)[0] == np.shape(x)[0]:
74
+ y= y.T
72
75
 
73
76
  if zlim!=0:
74
77
  sdbs=ax1.pcolormesh(x,y,z,cmap=cmap,rasterized=True,linewidth=0,vmin=zlim[0],vmax=zlim[1])
@@ -401,7 +401,8 @@ class BaseClassData:
401
401
 
402
402
  def add_cbar_hist(self):
403
403
  self.hax=self.cbar.ax.inset_axes([-1.05, 0, 1, 1],picker=True)
404
- counts, self.cbar_hist_bins = np.histogram(self.processed_data[-1],bins=int(self.settings['cmap levels']))
404
+ counts, self.cbar_hist_bins = np.histogram(self.processed_data[-1],bins=int(self.settings['cmap levels']),
405
+ range=(np.nanmin(self.processed_data[-1]), np.nanmax(self.processed_data[-1])))
405
406
  midpoints = self.cbar_hist_bins[:-1] + np.diff(self.cbar_hist_bins)/2
406
407
  self.hax.fill_between(-counts, midpoints,0,color='mediumslateblue')
407
408
  self.haxfill=self.hax.fill_betweenx(np.linspace(self.view_settings['Minimum'], self.view_settings['Maximum'], 100),
@@ -448,7 +449,7 @@ class BaseClassData:
448
449
  norm=norm, cmap=cmap,
449
450
  rasterized=self.settings['rasterized'])
450
451
  if self.settings['colorbar'] == 'True':
451
- self.cbar = self.figure.colorbar(self.image, orientation='vertical')
452
+ self.cbar = self.figure.colorbar(self.image)
452
453
  if self.view_settings['CBarHist'] == True:
453
454
  self.add_cbar_hist()
454
455
 
@@ -884,7 +885,7 @@ class MixedInternalData(BaseClassData):
884
885
  norm=norm, cmap=cmap,
885
886
  rasterized=self.dataset2d.settings['rasterized'])
886
887
  if self.dataset2d.settings['colorbar'] == 'True':
887
- self.cbar = self.figure.colorbar(self.image, orientation='vertical')
888
+ self.cbar = self.figure.colorbar(self.image)
888
889
  if self.view_settings['CBarHist'] == True:
889
890
  self.add_cbar_hist()
890
891
 
@@ -933,7 +934,9 @@ class MixedInternalData(BaseClassData):
933
934
 
934
935
  def add_cbar_hist(self):
935
936
  self.hax=self.cbar.ax.inset_axes([-1.05, 0, 1, 1],picker=True)
936
- counts, self.cbar_hist_bins = np.histogram(self.dataset2d.processed_data[-1],bins=int(self.settings['cmap levels']))
937
+ counts, self.cbar_hist_bins = np.histogram(self.dataset2d.processed_data[-1],bins=int(self.settings['cmap levels']),
938
+ range=(np.nanmin(self.dataset2d.processed_data[-1]),
939
+ np.nanmax(self.dataset2d.processed_data[-1])))
937
940
  midpoints = self.cbar_hist_bins[:-1] + np.diff(self.cbar_hist_bins)/2
938
941
  self.hax.fill_between(-counts, midpoints,0,color='mediumslateblue')
939
942
  self.haxfill=self.hax.fill_betweenx(np.linspace(self.view_settings['Minimum'], self.view_settings['Maximum'], 100),
@@ -1024,8 +1024,9 @@ class Editor(QtWidgets.QMainWindow, design.Ui_MainWindow):
1024
1024
 
1025
1025
  def reinstate_markers(self, item, orientation):
1026
1026
  orientations={'horizontal':'horimarkers','vertical':'vertmarkers'}
1027
- arrayname=orientations[orientation]
1028
- setattr(item.data,arrayname,[])
1027
+ if orientation != 'diagonal':
1028
+ arrayname=orientations[orientation]
1029
+ setattr(item.data,arrayname,[])
1029
1030
  if orientation == 'horizontal':
1030
1031
  for line in item.data.linecuts['horizontal']['lines']:
1031
1032
  z=item.data.linecuts[orientation]['lines'][line]['cut_axis_value']
@@ -1041,6 +1042,14 @@ class Editor(QtWidgets.QMainWindow, design.Ui_MainWindow):
1041
1042
  color=item.data.linecuts[orientation]['lines'][line]['linecolor']))
1042
1043
  item.data.vertmarkers.append(item.data.axes.axvline(x=z, linestyle='dashed', linewidth=1, ymin=0.9,
1043
1044
  color=item.data.linecuts[orientation]['lines'][line]['linecolor']))
1045
+
1046
+ elif orientation == 'diagonal':
1047
+ for line in item.data.linecuts[orientation]['lines']:
1048
+ points0= item.data.linecuts[orientation]['lines'][line]['points'][0]
1049
+ points1= item.data.linecuts[orientation]['lines'][line]['points'][1]
1050
+ item.data.linecuts[orientation]['lines'][line]['draggable_points']=[DraggablePoint(item.data, points0[0], points0[1],
1051
+ line,orientation),
1052
+ DraggablePoint(item.data, points1[0], points1[1],line,orientation,draw_line=True)]
1044
1053
 
1045
1054
  def clear_sidebar1D(self):
1046
1055
  # clear the sidebar1D
@@ -1074,7 +1083,7 @@ class Editor(QtWidgets.QMainWindow, design.Ui_MainWindow):
1074
1083
  item.data.axes = item.data.figure.add_subplot(rows, cols, index+1)
1075
1084
  item.data.add_plot(editor_window=self)
1076
1085
  if hasattr(item.data, 'linecuts'):
1077
- for orientation in ['horizontal','vertical']:#,'diagonal']:#,'circular']:
1086
+ for orientation in ['horizontal', 'vertical', 'diagonal']:
1078
1087
  if len(item.data.linecuts[orientation]['lines']) > 0:
1079
1088
  self.reinstate_markers(item,orientation)
1080
1089
  if item.data.linecuts[orientation]['linecut_window'] is not None and item==self.file_list.currentItem():
@@ -1474,7 +1483,7 @@ class Editor(QtWidgets.QMainWindow, design.Ui_MainWindow):
1474
1483
  else:
1475
1484
  item.data.filters = filters
1476
1485
 
1477
- else: # A filter is being appended
1486
+ else: # A filter is being appended to the table
1478
1487
  if isinstance(item.data,MixedInternalData) and self.mixeddata_filter_box.currentIndex() == 0:
1479
1488
  item.data.dataset2d.filters.append(filt)
1480
1489
  elif hasattr(item.data, 'sidebar1D'):
@@ -1485,6 +1494,9 @@ class Editor(QtWidgets.QMainWindow, design.Ui_MainWindow):
1485
1494
  filt.method_list.remove('Z')
1486
1495
  if hasattr(filt, 'method') and filt.method == 'Z':
1487
1496
  filt.method=filt.method_list[0]
1497
+ elif filt.name == 'Sort':
1498
+ filt.method_list = ['']
1499
+ filt.method= ''
1488
1500
  if isinstance(item.data,MixedInternalData):
1489
1501
  item.data.dataset1d.plotted_lines[current_line]['filters'].append(filt)
1490
1502
  else:
@@ -2177,6 +2189,10 @@ class Editor(QtWidgets.QMainWindow, design.Ui_MainWindow):
2177
2189
  method_box.setCurrentIndex(filt.method_list.index(filt.method))
2178
2190
  setting_1 = QtWidgets.QTableWidgetItem(filt.settings[0])
2179
2191
  setting_2 = QtWidgets.QTableWidgetItem(filt.settings[1])
2192
+ if hasattr(filt, 'tooltips'):
2193
+ setting_1.setToolTip(filt.tooltips[0])
2194
+ if len(filt.tooltips) > 1:
2195
+ setting_2.setToolTip(filt.tooltips[1])
2180
2196
  method_box.currentIndexChanged.connect(lambda: self.filters_table_edited(setting_1))
2181
2197
  self.filters_table.setItem(row, 0, filter_item)
2182
2198
  self.filters_table.setCellWidget(row, 1, method_box)
@@ -2219,13 +2235,12 @@ class Editor(QtWidgets.QMainWindow, design.Ui_MainWindow):
2219
2235
  if ((row > 0 and to == -1) or
2220
2236
  (row < self.filters_table.rowCount()-1 and to == 1)):
2221
2237
  filters[row], filters[row+to] = filters[row+to], filters[row]
2222
- self.show_current_filters()
2223
- self.filters_table.setCurrentCell(row+to, 0)
2224
2238
  if (self.filters_table.item(row,0).checkState() and
2225
2239
  self.filters_table.item(row+to,0).checkState()):
2226
- current_item.data.apply_all_filters()
2227
2240
  self.update_plots(update_color_limits=True)
2228
- self.show_current_view_settings()
2241
+ else:
2242
+ self.show_current_filters()
2243
+ self.filters_table.setCurrentCell(row+to, 0)
2229
2244
 
2230
2245
  def save_image(self):
2231
2246
  current_item = self.file_list.currentItem()
@@ -7,7 +7,9 @@ Created on Thu Nov 9 20:05:23 2017
7
7
 
8
8
  import numpy as np
9
9
  from scipy import ndimage, signal
10
- from scipy.interpolate import interp1d, interp2d
10
+ from scipy.interpolate import LinearNDInterpolator, CloughTocher2DInterpolator, make_interp_spline
11
+
12
+ from qcodespp.plotting.analysis_tools import sort_lists
11
13
 
12
14
 
13
15
  # Filter definitions
@@ -15,16 +17,16 @@ from scipy.interpolate import interp1d, interp2d
15
17
  def derivative(data, method, times_x, times_y):
16
18
  times_x, times_y = int(times_x), int(times_y)
17
19
  if len(data) == 3:
18
- for _ in range(times_x):
19
- data[-1] = np.gradient(data[-1], data[0][:,0], axis=0)
20
20
  for _ in range(times_y):
21
- data[-1] = np.gradient(data[-1], data[1][0,:], axis=1)
21
+ data[-1]= np.array([np.gradient(data[-1][i,:], data[1][i,:]) for i in range(data[-1].shape[0])])
22
+ for _ in range(times_x):
23
+ data[-1]= np.array([np.gradient(data[-1][:,i], data[0][:,i]) for i in range(data[-1].shape[1])]).T
22
24
  elif len(data) == 2:
23
25
  for _ in range(times_y):
24
- data[-1] = np.gradient(data[-1], data[0])
26
+ data[-1] = np.gradient(data[-1], data[0])
25
27
  return data
26
28
 
27
- def integrate(data, method, times_x, times_y):
29
+ def cumulative_sum(data, method, times_x, times_y):
28
30
  times_x, times_y = int(times_x), int(times_y)
29
31
  if len(data) == 3:
30
32
  if method=='Z':
@@ -46,7 +48,53 @@ def integrate(data, method, times_x, times_y):
46
48
  for _ in range(times_x):
47
49
  data[0] = np.cumsum(data[0])
48
50
 
49
- return data
51
+ return data
52
+
53
+ def integrate_rectangle(x, y):
54
+ """
55
+ Numerically integrate y with respect to x. Should be the same as cumulative sum for regularly spaced x.
56
+ """
57
+ integrated_y = np.zeros_like(y)
58
+ for i in range(1, len(y)):
59
+ integrated_y[i] = integrated_y[i-1] + y[i] * (x[i] - x[i-1])
60
+ return integrated_y
61
+
62
+ def integrate_trapezoid(x,y):
63
+ """
64
+ Numerically integrate y with respect to x using the trapezoidal rule.
65
+ """
66
+ integrated_y = np.zeros_like(y)
67
+ for i in range(1,len(y)):
68
+ integrated_y[i] = integrated_y[i-1] + (y[i] + y[i-1]) * (x[i] - x[i-1]) / 2.0
69
+ return integrated_y
70
+
71
+ def integrate_simpson(x, y):
72
+ """
73
+ Numerically integrate y with respect to x using Simpson's rule.
74
+ """
75
+ integrated_y = np.zeros_like(y)
76
+ for i in range(1,len(y) - 1):
77
+ integrated_y[i] = integrated_y[i-1] + (y[i-1] + 4 * y[i] + y[i+1]) * (x[i+1] - x[i-1])/6
78
+ # Use trapezoidal rule for the last segment
79
+ integrated_y[-1] = integrated_y[-2] + (y[-1] + y[-2]) * (x[-1] - x[-2]) / 2.0
80
+
81
+ return integrated_y
82
+
83
+
84
+ def integrate(data, method, times_x, times_y):
85
+ times_x, times_y = int(times_x), int(times_y)
86
+ functions={'Trapezoid': integrate_trapezoid, 'Simpson': integrate_simpson, 'Rectangle': integrate_rectangle}
87
+ if len(data) == 3:
88
+ for _ in range(times_x):
89
+ data[-1] = np.array([functions[method](data[-1][:,i], data[0][:,i]) for i in range(data[-1].shape[1])]).T
90
+ for _ in range(times_y):
91
+ data[-1] = np.array([functions[method](data[-1][i,:], data[1][i,:]) for i in range(data[-1].shape[0])])
92
+
93
+ elif len(data) == 2:
94
+ for _ in range(times_y):
95
+ data[-1] = functions[method](data[0], data[1])
96
+
97
+ return data
50
98
 
51
99
  def smooth(data, method, width_x, width_y):
52
100
  filters = {'Gauss': ndimage.gaussian_filter,
@@ -163,7 +211,10 @@ def cut_y(data, method, bottom, width):
163
211
  return data
164
212
 
165
213
  def swap_xy(data, method, setting1, setting2):
166
- data[0], data[1] = data[1], data[0]
214
+ if len(data) == 3:
215
+ data[0], data[1], data[-1] = data[1].T, data[0].T, data[-1].T
216
+ elif len(data) == 2:
217
+ data[0], data[1] = data[1], data[0]
167
218
  return data
168
219
 
169
220
  def flip(data, method, setting1, setting2):
@@ -388,23 +439,51 @@ def root(data, method, setting1, setting2):
388
439
  data[axis[method]][j] = np.abs(data[axis[method]][j])**(1/float(setting1))
389
440
  return data
390
441
 
442
+ def interp2d(x, y, z, kind='linear'):
443
+ """
444
+ Re-do the job that scipy used to do
445
+ """
446
+ if kind == 'linear':
447
+ interpolator = LinearNDInterpolator(list(zip(x,y)), z)
448
+ elif kind == 'cubic':
449
+ interpolator = CloughTocher2DInterpolator(list(zip(x,y)), z)
450
+ return interpolator
451
+
391
452
  def interpolate(data, method, n_x, n_y):
453
+ n_x, n_y = int(n_x), int(n_y)
392
454
  if len(data) == 3:
393
- x, y = data[0][:,0], data[1][0,:]
394
- f_z = interp2d(y, x, data[2], kind=method)
395
- n_x, n_y = int(n_x), int(n_y)
396
- min_x, max_x = np.amin(data[0]), np.amax(data[0])
397
- min_y, max_y = np.amin(data[1]), np.amax(data[1])
398
- yp, xp = np.linspace(min_y, max_y, n_y), np.linspace(min_x, max_x, n_x)
399
- data[1], data[0] = np.meshgrid(yp, xp)
400
- data[2] = f_z(yp, xp)
455
+ x=data[0].flatten()
456
+ y=data[1].flatten()
457
+ z=data[2].flatten()
458
+ f_z = interp2d(x,y,z, kind=method)
459
+ X, Y = np.linspace(min(x), max(x), n_x), np.linspace(min(y), max(y), n_y)
460
+ X, Y = np.meshgrid(X, Y)
461
+ data[2] = np.ma.masked_invalid(f_z(X,Y).T)
462
+ data[0] = X.T
463
+ data[1] = Y.T
401
464
  elif len(data) == 2:
402
- f = interp1d(data[0], data[1], kind=method)
403
- n_x = int(n_x)
404
- min_x, max_x = np.amin(data[0]), np.amax(data[0])
405
- data[0] = np.linspace(min_x, max_x, n_x)
465
+ kind={'linear': 1, 'cubic': 3}
466
+ x,y=sort_lists(data[0], data[1])
467
+ f = make_interp_spline(x, y, kind[method])
468
+ data[0] = np.linspace(np.min(x), np.max(x), n_x)
406
469
  data[1] = f(data[0])
407
470
  return data
471
+
472
+ def sort(data, method, setting1, setting2):
473
+ if len(data) == 3:
474
+ if method == 'X':
475
+ xsort,zsort=np.zeros_like(data[-1]),np.zeros_like(data[-1])
476
+ for i in range(data[-1].shape[1]):
477
+ xsort[:,i],zsort[:,i]=sort_lists(data[0][:,i],data[-1][:,i])
478
+ data=[xsort, data[1], zsort]
479
+ elif method == 'Y':
480
+ ysort,zsort=np.zeros_like(data[-1]),np.zeros_like(data[-1])
481
+ for i in range(data[-1].shape[0]):
482
+ ysort[i,:],zsort[i,:]=sort_lists(data[1][i],data[-1][i])
483
+ data=[data[0], ysort, zsort]
484
+ elif len(data) == 2:
485
+ data[0], data[1] = sort_lists(data[0], data[1])
486
+ return data
408
487
 
409
488
  def add_slope(data, method, a_x, a_y):
410
489
  if len(data) == 3:
@@ -431,36 +510,49 @@ def invert(data, method, setting1, setting2):
431
510
 
432
511
 
433
512
  class Filter:
434
- DEFAULT_SETTINGS = {'Derivative': {'Method': ['Mid'],
513
+ DEFAULT_SETTINGS = {'Derivative': {'Method': [''],
435
514
  'Settings': ['0', '1'],
515
+ 'tooltips': ['Order in X', 'Order in Y'],
436
516
  'Function': derivative,
437
517
  'Checkstate': 2},
438
- 'Integrate': {'Method': ['Z','Y','X'],
518
+ 'Integrate': {'Method': ['Trapezoid','Simpson','Rectangle'],
439
519
  'Settings': ['0', '1'],
520
+ 'tooltips': ['Order in X', 'Order in Y'],
440
521
  'Function': integrate,
441
522
  'Checkstate': 2},
523
+ 'Cumulative sum': {'Method': ['Z','Y','X'],
524
+ 'Settings': ['0', '1'],
525
+ 'tooltips': ['Order in zero-th index', 'Order in first index'],
526
+ 'Function': cumulative_sum,
527
+ 'Checkstate': 2},
442
528
  'Smoothen': {'Method': ['Gauss', 'Median'],
443
529
  'Settings': ['0', '2'],
530
+ 'tooltips': ['Smoothing window in X', 'Smoothing window in Y'],
444
531
  'Function': smooth,
445
532
  'Checkstate': 2},
446
533
  'Savitzy-Golay smoothing': {'Method': ['Y','X','dY','dX','ddY','ddX'],
447
534
  'Settings': ['7', '2'],
535
+ 'tooltips': ['Smoothing window', 'Polynomial order'],
448
536
  'Function': sav_gol,
449
- 'Checkstate': 2},
537
+ 'Checkstate': 2},
450
538
  'Add/Subtract': {'Method': ['X','Y','Z'],
451
539
  'Settings': ['0', ''],
540
+ 'tooltips': ['Value'],
452
541
  'Function': offset,
453
542
  'Checkstate': 2},
454
543
  'Multiply': {'Method': ['X','Y','Z'],
455
544
  'Settings': ['1', ''],
545
+ 'tooltips': ['Value'],
456
546
  'Function': multiply,
457
547
  'Checkstate': 2},
458
548
  'Divide': {'Method': ['X','Y','Z'],
459
549
  'Settings': ['1', ''],
550
+ 'tooltips': ['Value'],
460
551
  'Function': divide,
461
552
  'Checkstate': 0},
462
553
  'Add Slope': {'Method': [''],
463
554
  'Settings': ['0', '-1'],
555
+ 'tooltips': ['Slope value in X', 'Slope value in Y'],
464
556
  'Function': add_slope,
465
557
  'Checkstate': 2},
466
558
  'Invert': {'Method': ['X','Y','Z'],
@@ -469,6 +561,7 @@ class Filter:
469
561
  'Checkstate': 0},
470
562
  'Normalize': {'Method': ['Max', 'Min', 'Min to Max','Point'],
471
563
  'Settings': ['', ''],
564
+ 'tooltips': ['X coordinate', 'Y coordinate'],
472
565
  'Function': normalize,
473
566
  'Checkstate': 2},
474
567
  'Subtract average': {'Method': ['Z', 'Y', 'X'],
@@ -476,7 +569,8 @@ class Filter:
476
569
  'Function': subtract_average,
477
570
  'Checkstate': 2},
478
571
  'Offset line by line': {'Method': ['Z', 'Y'],
479
- 'Settings': ['', ''],
572
+ 'Settings': ['0', ''],
573
+ 'tooltips': ['Index'],
480
574
  'Function': offset_line_by_line,
481
575
  'Checkstate': 2},
482
576
  'Subtract average line by line': {'Method': ['Z', 'Y'],
@@ -485,18 +579,22 @@ class Filter:
485
579
  'Checkstate': 2},
486
580
  'Subtract trace': {'Method': ['Ver', 'Hor'],
487
581
  'Settings': ['0', ''],
582
+ 'tooltips': ['Index'],
488
583
  'Function': subtract_trace,
489
584
  'Checkstate': 0},
490
585
  'Logarithm': {'Method': ['Mask','Shift','Abs'],
491
586
  'Settings': ['10', ''],
587
+ 'tooltips': ['Base; 10, 2 or e'],
492
588
  'Function': logarithm,
493
589
  'Checkstate': 2},
494
590
  'Power': {'Method': ['X','Y','Z'],
495
591
  'Settings': ['2', ''],
592
+ 'tooltips': ['Exponent'],
496
593
  'Function': power,
497
594
  'Checkstate': 2},
498
595
  'Root': {'Method': ['X','Y','Z'],
499
596
  'Settings': ['2', ''],
597
+ 'tooltips': ['Exponent'],
500
598
  'Function': root,
501
599
  'Checkstate': 2},
502
600
  'Absolute': {'Method': [''],
@@ -507,32 +605,43 @@ class Filter:
507
605
  'Settings': ['', ''],
508
606
  'Function': flip,
509
607
  'Checkstate': 2},
510
- 'Interp': {'Method': ['linear','cubic','quintic'],
608
+ 'Interpolate': {'Method': ['linear','cubic'],
511
609
  'Settings': ['800', '600'],
610
+ 'tooltips': ['Number of points in X', 'Number of points in Y'],
512
611
  'Function': interpolate,
513
612
  'Checkstate': 0},
613
+ 'Sort': {'Method': ['X','Y'],
614
+ 'Settings': ['', ''],
615
+ 'Function': sort,
616
+ 'Checkstate': 2},
514
617
  'Roll X': {'Method': ['Index'],
515
618
  'Settings': ['0', '0'],
619
+ 'tooltips': ['Position', 'Amount'],
516
620
  'Function': roll_x,
517
621
  'Checkstate': 0},
518
622
  'Roll Y': {'Method': ['Index'],
519
623
  'Settings': ['0', '0'],
624
+ 'tooltips': ['Position', 'Amount'],
520
625
  'Function': roll_y,
521
626
  'Checkstate': 0},
522
627
  'Crop X': {'Method': ['Abs', 'Rel', 'Lim'],
523
628
  'Settings': ['-1', '1'],
629
+ 'tooltips': ['Min', 'Max'],
524
630
  'Function': crop_x,
525
631
  'Checkstate': 0},
526
632
  'Crop Y': {'Method': ['Abs', 'Rel', 'Lim'],
527
- 'Settings': ['-2', '2'],
633
+ 'Settings': ['-1', '1'],
634
+ 'tooltips': ['Min', 'Max'],
528
635
  'Function': crop_y,
529
636
  'Checkstate': 0},
530
637
  'Cut X': {'Method': ['Index'],
531
638
  'Settings': ['0', '0'],
639
+ 'tooltips': ['Left index', 'Width'],
532
640
  'Function': cut_x,
533
641
  'Checkstate': 0},
534
642
  'Cut Y': {'Method': ['Index'],
535
643
  'Settings': ['0', '0'],
644
+ 'tooltips': ['Bottom index', 'Width'],
536
645
  'Function': cut_y,
537
646
  'Checkstate': 0},
538
647
  'Swap X/Y': {'Method': [''],
@@ -541,7 +650,7 @@ class Filter:
541
650
  'Checkstate': 2},
542
651
  }
543
652
 
544
- def __init__(self, name, method=None, settings=None, checkstate=None):
653
+ def __init__(self, name, method=None, settings=None, checkstate=None, dimension=2):
545
654
  self.name = name
546
655
  default_settings = self.DEFAULT_SETTINGS.copy()
547
656
  self.method_list = default_settings[name]['Method']
@@ -558,4 +667,6 @@ class Filter:
558
667
  else:
559
668
  self.checkstate = default_settings[name]['Checkstate']
560
669
  self.function = default_settings[name]['Function']
670
+ if 'tooltips' in default_settings[name]:
671
+ self.tooltips = default_settings[name]['tooltips']
561
672
 
@@ -0,0 +1 @@
1
+ __version__ = '0.1.4'
@@ -1 +0,0 @@
1
- __version__ = '0.1.3'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes