NSFopen 2.2.1__tar.gz → 2.2.3__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 (60) hide show
  1. nsfopen-2.2.3/NSFopen/_version.py +1 -0
  2. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Force_Spectroscopy/Force_Spectroscopy.py +40 -23
  3. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/process/__init__.py +1 -1
  4. nsfopen-2.2.3/NSFopen/process/colormaps.py +71 -0
  5. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/process/process.py +220 -187
  6. nsfopen-2.2.3/NSFopen/read/read.py +647 -0
  7. {NSFopen-2.2.1 → nsfopen-2.2.3/NSFopen.egg-info}/PKG-INFO +1 -1
  8. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen.egg-info/SOURCES.txt +1 -0
  9. {NSFopen-2.2.1/NSFopen.egg-info → nsfopen-2.2.3}/PKG-INFO +1 -1
  10. NSFopen-2.2.1/NSFopen/_version.py +0 -1
  11. NSFopen-2.2.1/NSFopen/read/read.py +0 -526
  12. {NSFopen-2.2.1 → nsfopen-2.2.3}/LICENSE +0 -0
  13. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/__init__.py +0 -0
  14. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Calculate_Roughness/Calculate_Roughness.html +0 -0
  15. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Calculate_Roughness/Calculate_Roughness.ipynb +0 -0
  16. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Calculate_Roughness/Calculate_Roughness.py +0 -0
  17. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Calculate_Roughness/__pycache__/Calculate_Roughness.cpython-310.pyc +0 -0
  18. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Calculate_Roughness/sapphire.nid +0 -0
  19. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Force_Spectroscopy/Force_Spectroscopy.html +0 -0
  20. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Force_Spectroscopy/Force_Spectroscopy.ipynb +0 -0
  21. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Force_Spectroscopy/spectroscopy.nid +0 -0
  22. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Lateral_Force/Lateral Force Processing.html +0 -0
  23. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Lateral_Force/Lateral Force Processing.ipynb +0 -0
  24. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Lateral_Force/Lateral Force Processing.py +0 -0
  25. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Lateral_Force/SBS-PMMA.nid +0 -0
  26. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plane_Removal/Plane_Removal.html +0 -0
  27. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plane_Removal/Plane_Removal.ipynb +0 -0
  28. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plane_Removal/Plane_Removal.py +0 -0
  29. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plane_Removal/circles.nid +0 -0
  30. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plane_Removal/circles_holes.nid +0 -0
  31. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plane_Removal/grid.nid +0 -0
  32. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plane_Removal/squares_holes.nid +0 -0
  33. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plotting_Data/MoS2.nid +0 -0
  34. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plotting_Data/Plotting Data.html +0 -0
  35. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plotting_Data/Plotting Data.ipynb +0 -0
  36. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Plotting_Data/Plotting Data.py +0 -0
  37. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Sharpen_Image/Sharpen Image.html +0 -0
  38. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Sharpen_Image/Sharpen Image.ipynb +0 -0
  39. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Sharpen_Image/Sharpen Image.py +0 -0
  40. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Sharpen_Image/grid.nid +0 -0
  41. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Sharpen_Image/img.jpg +0 -0
  42. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Spring_Constant/Spring_Constant.html +0 -0
  43. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Spring_Constant/Spring_Constant.ipynb +0 -0
  44. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Spring_Constant/Spring_Constant.py +0 -0
  45. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Spring_Constant/__pycache__/Spring_Constant.cpython-310.pyc +0 -0
  46. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Spring_Constant/__pycache__/__init__.cpython-310.pyc +0 -0
  47. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Spring_Constant/sader.py +0 -0
  48. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Spring_Constant/thermal.nid +0 -0
  49. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/example/Spring_Constant/thermal.png +0 -0
  50. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/read/__init__.py +0 -0
  51. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen/read/read_beta.py +0 -0
  52. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen.egg-info/dependency_links.txt +0 -0
  53. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen.egg-info/entry_points.txt +0 -0
  54. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen.egg-info/not-zip-safe +0 -0
  55. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen.egg-info/requires.txt +0 -0
  56. {NSFopen-2.2.1 → nsfopen-2.2.3}/NSFopen.egg-info/top_level.txt +0 -0
  57. {NSFopen-2.2.1 → nsfopen-2.2.3}/README.md +0 -0
  58. {NSFopen-2.2.1 → nsfopen-2.2.3}/pyproject.toml +0 -0
  59. {NSFopen-2.2.1 → nsfopen-2.2.3}/setup.cfg +0 -0
  60. {NSFopen-2.2.1 → nsfopen-2.2.3}/setup.py +0 -0
@@ -0,0 +1 @@
1
+ __version__ = "2.2.3"
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
  # coding: utf-8
3
3
 
4
- # ## This script demonstrates how to open a Nanosurf Force Spectroscopy map and analyze the data using the DMT contact mechanics model
4
+ # ## This script demonstrates how to open a Nanosurf Force Spectroscopy map and analyze the data using the DMT contact mechanics model
5
5
 
6
6
  # In[1]:
7
7
 
@@ -16,23 +16,27 @@ from scipy.optimize import curve_fit
16
16
 
17
17
  from glob import glob
18
18
 
19
- filename = 'spectroscopy.nid'
20
- filename_large = 'spectroscopy_large.nid'
19
+ filename = "spectroscopy.nid"
20
+ filename_large = "spectroscopy_large.nid"
21
21
 
22
22
 
23
23
  # In[2]:
24
24
 
25
25
 
26
- # If USE_LARGE_MAP is True, then it will use the larger force-curve map, downloading if not already locally available
26
+ # If USE_LARGE_MAP is True, then it will use the larger force-curve map, downloading if not already locally available
27
27
  USE_LARGE_MAP = False
28
28
 
29
29
 
30
30
  # In[3]:
31
31
 
32
32
 
33
- if USE_LARGE_MAP and filename_large not in glob('*nid'):
33
+ if USE_LARGE_MAP and filename_large not in glob("*nid"):
34
34
  import urllib.request
35
- urllib.request.urlretrieve("https://www.dropbox.com/s/knzuh588g0uvjfi/spectroscopy_large.nid?dl=1", filename_large)
35
+
36
+ urllib.request.urlretrieve(
37
+ "https://www.dropbox.com/s/knzuh588g0uvjfi/spectroscopy_large.nid?dl=1",
38
+ filename_large,
39
+ )
36
40
  filename = filename_large
37
41
  elif USE_LARGE_MAP:
38
42
  filename = filename_large
@@ -47,20 +51,28 @@ data = afm.data
47
51
  param = afm.param
48
52
 
49
53
  # probe
50
- k = param.Tip.Prop0['Value'] # spring constant
51
- sens = param.Tip.Sensitivity['Value'] # deflection sensitivity (if needed)
54
+ k = param.Tip.Prop0["Value"] # spring constant
55
+ sens = param.Tip.Sensitivity["Value"] # deflection sensitivity (if needed)
52
56
 
53
57
  radius = 10e-9 # tip radius
54
58
  nu = 0.35 # Poisson ratio (between 0.35 and 0.5)
55
59
 
56
- spec_backward = data['Spec']['Backward'] # for DMT model we will use backward modulation
57
- d = spec_backward['Deflection'] # force channel
60
+ direction = "Backward" # Forward or Backward modulation
61
+
62
+ spec_backward = data["Spec"][
63
+ direction
64
+ ] # for DMT model we will use backward modulation
65
+ d = spec_backward["Deflection"] # force channel
58
66
 
59
67
  z_signal = list(spec_backward.index)
60
- z_chans = ['Z-Axis Sensor', 'Z-AxisSensor', 'Z-Axis'] # depending on system, Z-Axis channel may be labeled differently
68
+ z_chans = [
69
+ "Z-Axis Sensor",
70
+ "Z-AxisSensor",
71
+ "Z-Axis",
72
+ ] # depending on system, Z-Axis channel may be labeled differently
61
73
  available_chan = [i for i in z_signal if i in z_chans][0]
62
74
 
63
- z = data['Spec']['Backward'][available_chan] # Z-axis data
75
+ z = data["Spec"][direction][available_chan] # Z-axis data
64
76
 
65
77
  sz = int(param.Spec.maps[4]) # Map size
66
78
 
@@ -72,6 +84,7 @@ extent = param.Spec.maps[:4] # X and Y physical dimensions of map
72
84
 
73
85
  ## Functions
74
86
 
87
+
75
88
  # corrects for any baseline tilt
76
89
  def baseline_correct(x, y, degree=1, start=0, end=0.5):
77
90
  i0 = int(np.floor(len(x) * start))
@@ -90,14 +103,15 @@ def baseline_correct(x, y, degree=1, start=0, end=0.5):
90
103
  def DMT(x, *param):
91
104
  elast, depth, wadh = param
92
105
 
93
- scale = 4./3. * elast * np.sqrt(radius) / (1 - nu**2)
106
+ scale = 4.0 / 3.0 * elast * np.sqrt(radius) / (1 - nu**2)
94
107
  x = x - depth
95
- y = scale * np.sign(x) * np.abs(x)**(3./2.) - wadh
108
+ y = scale * np.sign(x) * np.abs(x) ** (3.0 / 2.0) - wadh
96
109
  return y
97
110
 
98
111
 
99
112
  def DMTfit(*args, maxForce=np.Inf):
100
113
  import time
114
+
101
115
  t = time.time()
102
116
  # args are: [separation, load (force)]
103
117
  if not isinstance(args[0], list):
@@ -108,7 +122,7 @@ def DMTfit(*args, maxForce=np.Inf):
108
122
  # x = x - y / spring_constant # separation
109
123
  lenY = int(np.floor(len(y) * 0.8))
110
124
  a = min(y[lenY:]) # adhesion
111
-
125
+
112
126
  i0 = np.where(y == a)[0][0] # contact point estimator index
113
127
  i1 = np.where(y > maxForce)[0] # max force index
114
128
 
@@ -118,13 +132,15 @@ def DMTfit(*args, maxForce=np.Inf):
118
132
  i1 = i1[0]
119
133
 
120
134
  try:
121
- coeff, var_matrix = curve_fit(DMT, x[i0:i1], y[i0:i1], p0=[1e9, x[i0], -a])
135
+ coeff, var_matrix = curve_fit(
136
+ DMT, x[i0:i1], y[i0:i1], p0=[1e9, x[i0], -a]
137
+ )
122
138
  except RuntimeError:
123
139
  E.append(np.nan)
124
140
  else:
125
141
  E.append(max(coeff[0], 0))
126
142
 
127
- print('Elapsed Time: %3.2f sec\n' % (time.time() - t))
143
+ print("Elapsed Time: %3.2f sec\n" % (time.time() - t))
128
144
  return np.array(E), (coeff, i0, i1)
129
145
 
130
146
 
@@ -135,7 +151,7 @@ def DMTfit(*args, maxForce=np.Inf):
135
151
  dd = [baseline_correct(z_, d_, start=0.5, end=0.8) for z_, d_ in zip(z, d)]
136
152
 
137
153
  # separation
138
- zz = [zz - dd/k for dd, zz in zip(dd, z)]
154
+ zz = [zz - dd / k for dd, zz in zip(dd, z)]
139
155
 
140
156
  # elastic modulus
141
157
  Eb, _ = DMTfit(zz, dd)
@@ -159,14 +175,16 @@ Adh = toMap(adh, sz)
159
175
  # In[7]:
160
176
 
161
177
 
162
- fig, ax = plt.subplots(2, 2, figsize=(10, 8), gridspec_kw={'height_ratios': [2, 1]}, dpi=300)
178
+ fig, ax = plt.subplots(
179
+ 2, 2, figsize=(10, 8), gridspec_kw={"height_ratios": [2, 1]}, dpi=300
180
+ )
163
181
  fig.tight_layout(w_pad=8.0, h_pad=1.0)
164
182
 
165
183
  im = ax.copy()
166
184
 
167
185
  cmap = "afmhot" # colormap
168
- xlbl = 'X [$\mu$m]'
169
- ylbl = 'Y [$\mu$m]'
186
+ xlbl = "X [$\mu$m]"
187
+ ylbl = "Y [$\mu$m]"
170
188
  zlbl = ["Young's Modulus [GPa]", "Adhesion [nN]"]
171
189
 
172
190
  im[0, 0] = ax[0, 0].imshow(Ebim)
@@ -182,8 +200,7 @@ for i in range(2):
182
200
  cb.set_label(zlbl[i])
183
201
 
184
202
  ax[0, i].set(xlabel=xlbl, ylabel=ylbl)
185
- ax[1, i].set(xlabel=zlbl[i], ylabel='Counts')
203
+ ax[1, i].set(xlabel=zlbl[i], ylabel="Counts")
186
204
 
187
205
 
188
206
  plt.show()
189
-
@@ -5,4 +5,4 @@ Created on Sat Oct 12 12:43:59 2019
5
5
  @author: Edward
6
6
  """
7
7
 
8
- from . process import process
8
+ from . process import process, colormaps
@@ -0,0 +1,71 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Thu May 23 13:04:53 2024
4
+
5
+ @author: nelson
6
+ """
7
+
8
+ import numpy as np
9
+ import pandas as pd
10
+ import os
11
+
12
+ from matplotlib.colors import LinearSegmentedColormap
13
+
14
+
15
+ class colors:
16
+ def __init__(self, name=None, gwy_dir=None, **kwargs):
17
+ self.name = name
18
+ self.gwy_dir = gwy_dir
19
+ if not gwy_dir:
20
+ self.gwy_dir = (
21
+ "C:\\Program Files\\Gwyddion\\share\\gwyddion\\gradients\\"
22
+ )
23
+ custom = ["BlueBlackRed"]
24
+ gwy_list = os.listdir(self.gwy_dir)
25
+
26
+ cmaps = {}
27
+ cmaps["Custom"] = custom
28
+ cmaps["Gwyddion"] = gwy_list
29
+
30
+ if name in gwy_list:
31
+ cmap = self.gwy_cmap()
32
+ elif name in custom:
33
+ cmap = self.custom()
34
+ else:
35
+ print("Name Not Found\n")
36
+ print("Use one of the following choices:\n")
37
+ print({x for v in cmaps.values() for x in v})
38
+ cmap = []
39
+ self.cmap = cmap
40
+ self.cmap_list = cmaps
41
+
42
+ def gwy_cmap(self):
43
+ cmap = pd.read_csv(
44
+ self.gwy_dir + self.name,
45
+ sep=" ",
46
+ header=None,
47
+ skiprows=1,
48
+ index_col=0,
49
+ )
50
+ nodes = cmap.index.values
51
+ colors = cmap.values
52
+
53
+ return LinearSegmentedColormap.from_list(
54
+ self.name, list(zip(nodes, colors))
55
+ )
56
+
57
+ def custom(self):
58
+ if self.name == "BlueBlackRed":
59
+ # Blue-Black-Red
60
+ start = np.array(
61
+ [0.6196078431372549, 0.792156862745098, 0.8823529411764706]
62
+ )
63
+ mid = np.array([0, 0, 0])
64
+ end = np.array(
65
+ [0.9882352941176471, 0.5725490196078431, 0.4470588235294118]
66
+ )
67
+ nodes = [0, 0.5, 1]
68
+
69
+ return LinearSegmentedColormap.from_list(
70
+ self.name, list(zip(nodes, [start, mid, end]))
71
+ )