diff --git a/doc/html/_page_projections.html b/doc/html/_page_projections.html new file mode 100644 index 0000000..103a183 --- /dev/null +++ b/doc/html/_page_projections.html @@ -0,0 +1,116 @@ + + + + + + + +PEARL Procedures: Projections + + + + + + + + + + + + + + +
+
+ + + + + + +
+
PEARL Procedures +  rev-distro-2.0.3-0-g0fb0fd9 +
+
Igor procedures for the analysis of PEARL data
+
+
+ + + + + + + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
Projections
+
+
+

the functions of the anglescan package support the following map projections.

+

for a description of the different projections, see, for example, https://en.wikipedia.org/wiki/Map_projection

+ + + + + + + + + + + + + +
Selector Projection Function Properties
kProjDist = 0 azimuthal equidistant r = c * theta radius is proportional to polar angle.
kProjStereo = 1 stereographic r = c * tan theta/2 circles on sphere map to circles.
kProjArea = 2 azimuthal equal-area r = c * sin theta/2 preserves area measure.
kProjGnom = 3 gnomonic r = c * tan theta great circles map to straight lines.
kProjOrtho = 4 orthographic r = c * sin theta k-space mapping in ARPES and LEED.
+

the projections in this package are defined for 0 <= theta < 90.

+
+
+ + + + diff --git a/doc/html/anglescan-processing_8dox.html b/doc/html/anglescan-processing_8dox.html index 33b064c..7048c1a 100644 --- a/doc/html/anglescan-processing_8dox.html +++ b/doc/html/anglescan-processing_8dox.html @@ -29,7 +29,7 @@
PEARL Procedures -  rev-distro-2.0.2-0-g3235d52 +  rev-distro-2.0.3-0-g0fb0fd9
Igor procedures for the analysis of PEARL data
@@ -91,7 +91,7 @@ $(document).ready(function(){initNavTree('anglescan-processing_8dox.html','');}) - + - - + + + +
- + - - + + + +
-
D | E
+
d | e
-
  D  
+
  d  
  e  
DoniachSunjicStruct   errorCode   
-
D | E
+
d | e
diff --git a/doc/html/dir_fe5dc42579d4b99403482a3a637d9f7d.html b/doc/html/dir_fe5dc42579d4b99403482a3a637d9f7d.html index b4d5f0a..e2371d5 100644 --- a/doc/html/dir_fe5dc42579d4b99403482a3a637d9f7d.html +++ b/doc/html/dir_fe5dc42579d4b99403482a3a637d9f7d.html @@ -29,7 +29,7 @@
PEARL Procedures -  rev-distro-2.0.2-0-g3235d52 +  rev-distro-2.0.3-0-g0fb0fd9
Igor procedures for the analysis of PEARL data
@@ -89,42 +89,56 @@ $(document).ready(function(){initNavTree('dir_fe5dc42579d4b99403482a3a637d9f7d.h

Files

file  fermi-edge-analysis.ipf [code] + tools for analysing the Fermi edge measured by the Scienta EW4000 analyser.
  file  pearl-anglescan-panel.ipf [code] + interactive processing of angle scanned XPD data.
  file  pearl-anglescan-process.ipf [code] + processing and holographic mapping of angle scanned XPD data.
  file  pearl-anglescan-tracker.ipf [code]   file  pearl-area-display.ipf [code] + visualization tools for 2D and 3D data.
  file  pearl-area-import.ipf [code] + HDF5 file import from EPICS area detectors.
  file  pearl-area-profiles.ipf [code] + profile extraction for multi-dimensional datasets acquired from area detectors.
  file  pearl-arpes.ipf [code] + data acquisition and analysis package for ARPES at PEARL.
  file  pearl-data-explorer.ipf [code] + preview and import panel for PEARL data
  file  pearl-elog.ipf [code] + interface for writing ELOG entries with Igor graphs as attachment.
  file  pearl-fitfuncs.ipf [code] + various fit functions for photoelectron spectroscopy.
  file  pearl-gui-tools.ipf [code]   file  pearl-matrix-import.ipf [code] + data file import for omicron matrix (STM) files
  file  pearl-menu.ipf [code]   file  pearl-otf-import.ipf [code]   file  pearl-pmsco-import.ipf [code] + data import/export procedures for multiple scattering calculations.
  file  pearl-polar-coordinates.ipf [code]   file  pearl-pshell-import.ipf [code] + import data from PShell
  file  pearl-scienta-preprocess.ipf [code] + preprocessing functions for Scienta detector images.
  file  pearl-tools.ipf [code]   @@ -137,7 +151,7 @@ Files
+
+Functions | +Variables
-
fermi-edge-analysis.ipf File Reference
+
fermi-edge-analysis.ipf File Reference
+

tools for analysing the Fermi edge measured by the Scienta EW4000 analyser. +More...

+
#include "pearl-area-profiles"
+

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + +

+Functions

variable analyse_curved_edge (wave data)
 
variable record_results (variable index)
 
variable integrate_curved_edge (wave data, wave data_sig)
 
variable slit_correction (wave data, wave data_out, variable epass)
 
threadsafe variable FermiFuncLinDOS2D_corr (variable w, threadsafe x, wave y)
 
threadsafe variable slit_shift (variable ypix, variable epass)
 
variable show_shift (wave data)
 
variable analyser_energy_resolution (variable epass, variable slit)
 calculate the energy resolution of the analyser More...
 
+ + + + + + + + + + + + + +

+Variables

static const variable mcp_radius_pix = 555
 MCP radius seen by the camera in pixels. More...
 
static const variable mcp_radius_mm = 20
 physical size (radius) of the MCP in mm More...
 
static const variable hemi_radius_mm = 200
 physical size (radius) of the hemisphere in mm More...
 
static const variable mcp_radius_epass = 0.04
 energy range imaged on MCP relative to the pass energy More...
 
+

Detailed Description

+

tools for analysing the Fermi edge measured by the Scienta EW4000 analyser.

+

proposed procedure

+ +
Author
matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
+
+thomas dienel
+ + +

Definition in file fermi-edge-analysis.ipf.

+

Function Documentation

+ +

◆ analyse_curved_edge()

+ +
+
+ + + + + + + + +
variable analyse_curved_edge (wave data)
+
+ +

Definition at line 27 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ analyser_energy_resolution()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable analyser_energy_resolution (variable epass,
variable slit 
)
+
+ +

calculate the energy resolution of the analyser

+
Parameters
+ + + +
epasspass energy in eV
slitanalyser entrance slit in mm
+
+
+
Returns
energy resolution (FWHM)
+ +

Definition at line 306 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ FermiFuncLinDOS2D_corr()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
threadsafe variable FermiFuncLinDOS2D_corr (variable w,
threadsafe x,
wave y 
)
+
+ +

Definition at line 216 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ integrate_curved_edge()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable integrate_curved_edge (wave data,
wave data_sig 
)
+
+ +

Definition at line 116 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ record_results()

+ +
+
+ + + + + + + + +
variable record_results (variable index)
+
+ +

Definition at line 98 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ show_shift()

+ +
+
+ + + + + + + + +
variable show_shift (wave data)
+
+ +

Definition at line 284 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ slit_correction()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
variable slit_correction (wave data,
wave data_out,
variable epass 
)
+
+ +

Definition at line 173 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ slit_shift()

+ +
+
+ + + + + + + + + + + + + + + + + + +
threadsafe variable slit_shift (variable ypix,
variable epass 
)
+
+ +

Definition at line 267 of file fermi-edge-analysis.ipf.

+ +
+
+

Variable Documentation

+ +

◆ hemi_radius_mm

+ +
+
+ + + + + +
+ + + + +
const variable hemi_radius_mm = 200
+
+static
+
+ +

physical size (radius) of the hemisphere in mm

+ +

Definition at line 263 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ mcp_radius_epass

+ +
+
+ + + + + +
+ + + + +
const variable mcp_radius_epass = 0.04
+
+static
+
+ +

energy range imaged on MCP relative to the pass energy

+ +

Definition at line 265 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ mcp_radius_mm

+ +
+
+ + + + + +
+ + + + +
const variable mcp_radius_mm = 20
+
+static
+
+ +

physical size (radius) of the MCP in mm

+ +

Definition at line 261 of file fermi-edge-analysis.ipf.

+ +
+
+ +

◆ mcp_radius_pix

+ +
+
+ + + + + +
+ + + + +
const variable mcp_radius_pix = 555
+
+static
+
+ +

MCP radius seen by the camera in pixels.

+ +

Definition at line 259 of file fermi-edge-analysis.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #include "pearl-area-profiles"
3 
4 // $Id$
5 
25 
26 
27 function analyse_curved_edge(data)
28  wave data // 2D counts data, x-scale = kinetic energy, y-scale = analyser angle
29  variable guess_EF // initial guess of the Fermi level
30 
31  dfref savedf = GetDataFolderDFR()
32  dfref datadf = GetWavesDataFolderDFR(data)
33  setdatafolder datadf
34 
35  make /n=5 /d /o w_coef_int
36  make /n=7 /d /o w_coef_curved
37 
38  // 1) integrate data
39  wave xint = ad_profile_x(data, -inf, inf, "", noavg=1)
40  duplicate /free xint, xint_sig
41  xint_sig = sqrt(xint * 4) / 4
42  variable xmin = wavemin(xint)
43  variable xmax = wavemax(xint)
44  variable xmean = mean(xint)
45 
46  // 2) fit integrated data for reference
47  w_coef_int[0] = xmin
48  w_coef_int[1] = 0
49  w_coef_int[2] = xmax - xmin
50  w_coef_int[3] = dimoffset(xint, 0) + dimdelta(xint, 0) * dimsize(xint, 0) / 2
51  w_coef_int[4] = 100
52  FuncFit /NTHR=0 FermiFuncLinDOS w_coef_int xint /D /I=1 /W=xint_sig
53  wave w_sigma
54  duplicate /o w_sigma, w_sigma_int
55 
56  // 3) normalize data
57  wave yavg = ad_profile_y(data, -inf, inf, "")
58  variable ymean = mean(yavg)
59 
60  duplicate /o data, data_norm, data_sig
61  data_sig = sqrt(data * 4) / 4
62  data_norm = data_norm * ymean / yavg[q]
63  data_sig = data_sig * ymean / yavg[q]
64 
65  // 4) fit normalized data
66  wave xavg = ad_profile_x(data, -inf, inf, "")
67  xmin = wavemin(xavg)
68  xmax = wavemax(xavg)
69  xmean = mean(xavg)
70 
71  w_coef_curved[0] = {0, 0, 1, 95.5, 100, 0, -0.0001}
72  w_coef_curved[0] = xmin
73  w_coef_curved[2] = xmax - xmin
74  w_coef_curved[3] = w_coef_int[3]
75  w_coef_curved[4] = w_coef_int[4]
76 
77  //variable box = min(11, numpnts(xavg) / 5)
78  //FindLevel /B=(box) /EDGE=2 /Q xavg, (xmin + xmax) / 2
79  //if (v_flag == 0)
80  // w_coef_curved[3] = v_levelx
81  //else
82  // w_coef_curved[3] = dimoffset(data, 0) + dimdelta(data, 0) * dimsize(data, 0) / 2
83  //endif
84 
85  duplicate /o data_norm, fit_data_norm
86  FuncFitMD /X=1 /NTHR=0 FermiFuncLinDOS_2Dcorr w_coef_curved data_norm /D=fit_data_norm /I=1 /W=data_sig
87  wave w_sigma
88  duplicate /o w_sigma, w_sigma_curved
89 
90  display /k=1; appendimage data_norm
91  ModifyImage data_norm ctab= {xmin,xmax,Grays,0}
92  AppendMatrixContour fit_data_norm
93 
94  setdatafolder savedf
95  return 0
96 end
97 
98 function record_results(index)
99  variable index
100 
101  dfref savedf = GetDataFolderDFR()
102  wave /sdfr=root: Tint, Tint_sig, Tcurv, Tcurv_sig, EFcurv, EFcurv_sig
103  wave w_coef_int, w_coef_curved
104  wave w_sigma_int, w_sigma_curved
105 
106  Tint[index] = w_coef_int[4]
107  Tint_sig[index] = w_sigma_int[4]
108  Tcurv[index] = w_coef_curved[4]
109  Tcurv_sig[index] = w_sigma_curved[4]
110  EFcurv[index] = w_coef_curved[3]
111  EFcurv_sig[index] = w_sigma_curved[3]
112 
113  setdatafolder savedf
114 end
115 
116 function integrate_curved_edge(data, data_sig)
117  wave data
118  wave /z data_sig
119  //wave coef
120 
121  string name = nameofwave(data)
122 
123  duplicate /o data, data_out
124  redimension /n=(dimsize(data,0)) data_out
125  data_out = 0
126 
127  if (waveexists(data_sig))
128  duplicate /o data_sig, sig_out
129  redimension /n=(dimsize(data,0)) sig_out
130  sig_out = 0
131  endif
132 
133  wave ywgt = ad_profile_y(data, -inf, inf, "", noavg=1)
134  ywgt = 1 / ywgt / 4
135  //ywgt = 1 / 4
136  variable sum_ywgt = sum(ywgt)
137 
138  variable nx = dimsize(data, 0)
139  variable ny = dimsize(data, 1)
140  variable iy
141  variable yy
142  variable dx
143  variable dy
144  variable dp
145  variable dp_min = 0
146 
147  wave PassEnergy = :attr:PassEnergy
148  wave NumSlices = :attr:NumSlices
149 
150  for (iy = 0; iy < ny; iy += 1)
151  dy = dimoffset(data, 1) + dimdelta(data, 1) * iy
152  dy = dy / dimdelta(data, 1)
153  dx = slit_shift(dy * 902 / NumSlices[0], PassEnergy[0])
154  dp = round(dx / dimdelta(data, 0)) // <= 0
155  dp_min = min(dp_min, dp)
156 
157  data_out[] = p+dp >= 0 ? data_out + data[p+dp][iy] * ywgt[iy] : data_out
158 
159  if (waveexists(data_sig))
160  sig_out = p+dp >= 0 ? sig_out + data_sig[p+dp][iy] * ywgt[iy] : sig_out
161  endif
162  endfor
163 
164  data_out /= sum_ywgt
165  data_out[0, -dp_min][] = nan
166 
167  if (waveexists(sig_out))
168  sig_out /= sum_ywgt
169  //sig_out[0, -dp_min] = nan
170  endif
171 end
172 
173 function slit_correction(data, data_out, epass)
174  wave data // must be image with original dimensions (no cropping!)
175  wave /z data_out // 2D or 1D wave to receive the result
176  // X dimension must be identical to the one of data
177  // if 2D, Y dimension must be either identical to the one of data
178  // if 1D, the result will be the sum of the corrected slices
179  variable epass // pass energy
180 
181  if (!WaveExists(data_out))
182  string name = nameofwave(data) + "_corr"
183  duplicate /o data, $name
184  wave data_out = $name
185  //redimension /n=(dimsize(data,0)) data_out
186  endif
187  data_out = 0
188 
189  variable nx = dimsize(data, 0)
190  variable ny = dimsize(data, 1)
191  variable iy
192  variable yy
193  variable dx
194  variable dy
195  variable dp
196  variable dp_min = 0
197 
198  for (iy = 0; iy < ny; iy += 1)
199  dy = dimoffset(data, 1) + dimdelta(data, 1) * iy
200  dy = dy / dimdelta(data, 1)
201  dx = slit_shift(dy * 902 / ny, epass)
202  dp = round(dx / dimdelta(data, 0)) // <= 0
203  dp_min = min(dp_min, dp)
204 
205  if (wavedims(data_out) >= 2)
206  data_out[][iy] = p+dp >= 0 ? data_out + data[p+dp][iy] : data_out
207  else
208  data_out = p+dp >= 0 ? data_out + data[p+dp][iy] : data_out
209  endif
210  endfor
211 
212  data_out[0, -dp_min][] = nan
213 end
214 
215 //------------------------------------------------------------------------------
216 threadsafe Function FermiFuncLinDOS2D_corr(w,x,y) : FitFunc
217 // linear density of states below Fermi level
218 // 2D data with corrections:
219 // - straight slit (slit shift)
220 // - transmission function (polynomial)
221 //------------------------------------------------------------------------------
222  Wave w; Variable x; variable y
223  // w[0] = background far above the fermi level
224  // w[1] = slope of the linear background
225  // w[2] = amplitude
226  // w[3] = fermi level in eV
227  // w[4] = temperature in K
228  // w[5] = transmission - linear term
229  // w[6] = transmission - quadratic term
230  // w[7] = transmission - cubic term
231  // w[8] = pass energy (hold this value)
232  // w[9] = y scale: pixels / unit of y
233 
234  variable pos = w[3] + slit_shift(y * w[9], w[8])
235  variable transm = 1 + w[5] * y + w[6] * y^2 + w[7] * y^3
236  variable fermi = (w[1] * min(x - pos, 0) + w[2]) / ( exp( (x - pos) / (kBoltzmann * w[4]) ) + 1.0 )
237  return transm * (fermi + w[0])
238 end
239 
240 //------------------------------------------------------------------------------
241 threadsafe Function FermiFuncLinDOS_2Dcorr_old(w,x,y) : FitFunc
242 // linear density of states below Fermi level
243 // 2D data with a polynomial shift of the Fermi level in the second dimension
244 //------------------------------------------------------------------------------
245  Wave w; Variable x; variable y
246  // w[0] = background far above the fermi level
247  // w[1] = slope of the linear background
248  // w[2] = amplitude
249  // w[3] = fermi level in eV
250  // w[4] = temperature in K
251  // w[5] = shift - linear term
252  // w[6] = shift - quadratic term
253 
254  variable pos = w[3] + w[5] * y + w[6] * y^2
255  return w[0] + (w[1] * min(x - pos, 0) + w[2]) / ( exp( (x - pos) / (kBoltzmann * w[4]) ) + 1.0 )
256 end
257 
259 static constant mcp_radius_pix = 555
261 static constant mcp_radius_mm = 20
263 static constant hemi_radius_mm = 200
265 static constant mcp_radius_epass = 0.04
266 
267 threadsafe function slit_shift(ypix, epass)
268  // calculates the energy shift due to straight slit
269  // the radius of the curve is 1/2 of the hemisphere radius
270  variable ypix // vertical (angle/position) pixels distance from center
271  // = slice coordinate * 902 / number of slices
272  variable epass // pass energy
273 
274  variable rpix = mcp_radius_pix * hemi_radius_mm / mcp_radius_mm
275  //variable rpix = mcp_radius_pix * hemi_radius_mm / 2 / mcp_radius_mm
276  variable rene = epass * mcp_radius_epass * hemi_radius_mm / 2 / mcp_radius_mm
277 
278  variable isin = asin(ypix / rpix)
279  variable dene = rene * (cos(isin) - 1)
280 
281  return dene
282 end
283 
284 function show_shift(data)
285  wave data
286  variable epass
287 
288  variable ny = dimsize(data, 1)
289  make /o /n=(ny) shift_x
290  setscale /i x -ny/2, ny/2, "", shift_x
291  wave PassEnergy = :attr:PassEnergy
292  wave NumSlices = :attr:NumSlices
293 
294  shift_x = slit_shift(x * 902 / NumSlices[0], PassEnergy[0])
295 
296  variable ecenter = dimoffset(data, 0) + dimdelta(data, 0) * dimsize(data, 0) / 2
297  shift_x += ecenter
298 end
299 
306 function analyser_energy_resolution(epass, slit)
307  variable epass
308  variable slit
309 
310  variable respow
311  if (epass < 4)
312  respow = 1110
313  elseif (epass < 8)
314  respow = 1400
315  else
316  respow = 1750
317  endif
318 
319  return epass * max(0.2, slit) / 0.2 / respow
320 end
threadsafe variable FermiFuncLinDOS2D_corr(variable w, threadsafe x, wave y)
+
threadsafe variable slit_shift(variable ypix, variable epass)
+
static const variable mcp_radius_pix
MCP radius seen by the camera in pixels.
+
static const variable mcp_radius_mm
physical size (radius) of the MCP in mm
+
threadsafe wave ad_profile_y(wave dataset, variable p1, variable p2, string destname, variable noavg=defaultValue)
1D cut through 2D dataset along Y dimension, new destination wave.
+
variable analyse_curved_edge(wave data)
+
static const variable hemi_radius_mm
physical size (radius) of the hemisphere in mm
+
variable analyser_energy_resolution(variable epass, variable slit)
calculate the energy resolution of the analyser
+
variable slit_correction(wave data, wave data_out, variable epass)
+
static const variable mcp_radius_epass
energy range imaged on MCP relative to the pass energy
+
variable integrate_curved_edge(wave data, wave data_sig)
+
variable show_shift(wave data)
+
threadsafe wave ad_profile_x(wave dataset, variable q1, variable q2, string destname, variable noavg=defaultValue)
1D cut through 2D dataset along X dimension, new destination wave.
+
variable record_results(variable index)
+
+
+Functions
pearl-gui-tools.ipf File Reference

Go to the source code of this file.

+ + + + + + + + +

+Functions

variable display_progress_panel (string title, string message, variable progress_max)
 
variable update_progress_panel (variable progress, string message=defaultValue, variable progress_max=defaultValue)
 
variable kill_progress_panel ()
 
+

Function Documentation

+ +

◆ display_progress_panel()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
variable display_progress_panel (string title,
string message,
variable progress_max 
)
+
+ +

Definition at line 18 of file pearl-gui-tools.ipf.

+ +
+
+ +

◆ kill_progress_panel()

+ +
+
+ + + + + + + +
variable kill_progress_panel ()
+
+ +

Definition at line 50 of file pearl-gui-tools.ipf.

+ +
+
+ +

◆ update_progress_panel()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
variable update_progress_panel (variable progress,
string message = defaultValue,
variable progress_max = defaultValue 
)
+
+ +

Definition at line 32 of file pearl-gui-tools.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #pragma IgorVersion = 6.1
3 #pragma ModuleName = PearlGuiTools
4 #pragma version = 1.01
5 
6 // Miscellaneous GUI tools
7 // * progress bar
8 
9 // created: matthias.muntwiler@psi.ch, 2013-11-14
10 // Copyright (c) 2013 Paul Scherrer Institut
11 // $Id$
12 
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 // http://www.apache.org/licenses/LICENSE-2.0
17 
18 function display_progress_panel(title, message, progress_max)
19  string title
20  string message
21  variable progress_max
22 
23  NewPanel /K=1 /N=ProgressPanel /W=(200,200,402,260) as title
24  TitleBox t_message,pos={2,2},size={189,13},title=message
25  TitleBox t_message,frame=0
26  ValDisplay vd_progress,pos={2,20},size={198,13}
27  ValDisplay vd_progress,limits={0,progress_max,0},barmisc={0,0},mode= 3,value= _NUM:0
28  Button b_abort,pos={74,38},size={50,20},title="Abort"
29  DoUpdate /W=ProgressPanel /E=1
30 end
31 
32 function update_progress_panel(progress, [message, progress_max])
33  // returns true if the user clicked the Abort button
34  variable progress
35  string message
36  variable progress_max
37 
38  if (!ParamIsDefault(message))
39  TitleBox t_message,title=message,win=ProgressPanel
40  endif
41  if (ParamIsDefault(progress_max))
42  ValDisplay vd_progress,value=_NUM:progress,win=ProgressPanel
43  else
44  ValDisplay vd_progress,limits={0,progress_max,0},value=_NUM:progress,win=ProgressPanel
45  endif
46  DoUpdate /W=ProgressPanel
47  return (v_flag == 2)
48 end
49 
50 function kill_progress_panel()
51  KillWindow ProgressPanel
52 end
variable kill_progress_panel()
+
variable display_progress_panel(string title, string message, variable progress_max)
+
variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
+
+
+Data Structures | +Namespaces | +Functions | +Variables
pearl-matrix-import.ipf File Reference
+

data file import for omicron matrix (STM) files +More...

+

Go to the source code of this file.

+ + + + + +

+Data Structures

struct  errorCode
 from matrixfilereader help More...
 
+ + + + +

+Namespaces

 PearlMatrixImport
 data file import for omicron matrix (STM) files
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

static variable init_package ()
 initialize the package data folder. More...
 
static variable check_package_folder ()
 check that the package data folder exists More...
 
static variable AfterFileOpenHook (variable refNum, string file, string pathName, string type, string creator, variable kind)
 initialize the package and reload preferences after an experiment is loaded. More...
 
static variable BeforeFileOpenHook (variable refNum, string fileName, string path, string type, string creator, variable kind)
 open a matrix file that was dropped into Igor. More...
 
string matrix_format_elog_message (wave metadata)
 generate elog message from bricklet metadata More...
 
variable matrix_preview_2d (wave data, wave metadata)
 
static wave preview_matrix_file (string filename)
 load the preview of a Matrix data file More...
 
static variable initStruct (errorCode *errorCode)
 from matrixfilereader help More...
 
variable mtrx_load_all ()
 load all data from a Matrix data file. More...
 
variable mtrx_parse_filename (string fileName, string *resultFile, variable *runCycle, variable *scanCycle, string *channel)
 parse matrix file names More...
 
string mtrx_split_filename (string fileName, string *prefix, string *datepart, string *timepart)
 split a matrix filename and return the first three parts More...
 
dfr mtrx_create_folder (string fileName, dfref df_base=defaultValue)
 create or look up a data folder based on a matrix file name. More...
 
dfr mtrx_get_cycle_folder (dfref df_base=defaultValue, variable runCycle=defaultValue, variable scanCycle=defaultValue)
 create a data folder for bricklet data. More...
 
variable mtrx_file_brickletID (string resultFile, variable runCycle, variable scanCycle, string channel)
 find out bricklet ID of a file More...
 
variable mtrx_open_file (string pathName, string fileNameOrPath)
 open a matrix result or data file More...
 
string mtrx_load_preview (string destName, string pathName, string fileName, string traces=defaultValue)
 load a preview image from a Matrix data file. More...
 
string mtrx_load_file (string pathName, string fileName, string traces=defaultValue)
 load all data from a Matrix data file. More...
 
variable mtrx_scale_dataset (wave data)
 
string mtrx_load_info (string APathName, string AFileName)
 load descriptive info from a Matrix data file. More...
 
variable subtract_line_bg (wave img)
 remove linear background line-by-line More...
 
+ + + + + + + +

+Variables

static const string package_name = "pearl_matrix_import"
 
static const string package_path = "root:packages:pearl_matrix_import:"
 
static const string ks_filematch_mtrx = "*_mtrx"
 
+

Detailed Description

+

data file import for omicron matrix (STM) files

+

the matrix file import requires the matrix file reader XOP by thomas braun (http://www.igorexchange.com/project/matrixFileReader) which in turn requires an installation of vernissage by omicron nanotechnology.

+
Warning
EXPERIMENTAL the matrix import module and its interface may change radically in future revisions!
+
Author
matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
+ + +

Definition in file pearl-matrix-import.ipf.

+

Function Documentation

+ +

◆ AfterFileOpenHook()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static variable AfterFileOpenHook (variable refNum,
string file,
string pathName,
string type,
string creator,
variable kind 
)
+
+static
+
+ +

initialize the package and reload preferences after an experiment is loaded.

+ +

Definition at line 85 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ BeforeFileOpenHook()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static variable BeforeFileOpenHook (variable refNum,
string fileName,
string path,
string type,
string creator,
variable kind 
)
+
+static
+
+ +

open a matrix file that was dropped into Igor.

+

preliminary implementation. this should rather load the entire file and display a preview. graph windows should be reused by subsequent loads. also decide on a data saving location.

+ +

Definition at line 102 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ check_package_folder()

+ +
+
+ + + + + +
+ + + + + + + +
static variable check_package_folder ()
+
+static
+
+ +

check that the package data folder exists

+

initialize the package if the folder does not exist.

+ +

Definition at line 72 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ init_package()

+ +
+
+ + + + + +
+ + + + + + + +
static variable init_package ()
+
+static
+
+ +

initialize the package data folder.

+ +

Definition at line 45 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ initStruct()

+ +
+
+ + + + + +
+ + + + + + + + +
static variable initStruct (errorCodeerrorCode)
+
+static
+
+ +

from matrixfilereader help

+ +

Definition at line 212 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ matrix_format_elog_message()

+ +
+
+ + + + + + + + +
string matrix_format_elog_message (wave metadata)
+
+ +

generate elog message from bricklet metadata

+
Parameters
+ + +
metadatatwo-column text wave
+
+
+ +

Definition at line 120 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ matrix_preview_2d()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable matrix_preview_2d (wave data,
wave metadata 
)
+
+ +

Definition at line 145 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_create_folder()

+ +
+
+ + + + + + + + + + + + + + + + + + +
dfr mtrx_create_folder (string fileName,
dfref df_base = defaultValue 
)
+
+ +

create or look up a data folder based on a matrix file name.

+

the name of the folder is mtrx_date_time, where date and time are parsed from the file name. for this to work, the file name must consist of at least three parts that are separated by dash or underscore. the second (third) part contains the date (time). date and time are copied as strings.

+

if the data folder exists, a reference to the existing folder is returned.

+
Parameters
+ + + +
fileNamename of the result or data file.
df_base(optional) base data folder. default: current folder.
+
+
+
Returns
reference of the newly created or existing data folder.
+ +

Definition at line 360 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_file_brickletID()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable mtrx_file_brickletID (string resultFile,
variable runCycle,
variable scanCycle,
string channel 
)
+
+ +

find out bricklet ID of a file

+
Warning
EXPERIMENTAL the code of this function is inefficient. the function may be removed in a later version.
+
Parameters
+ + + + + +
resultFilebase name of result file without chain link number and extension. as returned by mtrx_parse_filename.
runCyclerequested run cycle. 0 = first available.
scanCyclerequested scan cycle. 0 = first available.
channelchannel name. for example: "I", "Z", "Aux(V)", etc. empty string: first available.
+
+
+
Returns
bricklet ID, or -1 if an error occurred.
+ +

Definition at line 461 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_get_cycle_folder()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
dfr mtrx_get_cycle_folder (dfref df_base = defaultValue,
variable runCycle = defaultValue,
variable scanCycle = defaultValue 
)
+
+ +

create a data folder for bricklet data.

+

the name of the folder is, for example "r23s2" where the first (second) number is the run (scan) cycle. run cycle and scan cycle numbers are taken from the open matrix file unless overridden by optional arguments.

+

if the data folder exists, a reference to the existing folder is returned. if one of the run or scan cycle numbers is lower than 1, the base folder is returned.

+
Parameters
+ + + + +
df_base(optional) base data folder. default: current folder.
runCycle(optional) run cycle number. must be >= 1. default: from last mtrx_open_file call.
scanCycle(optional) scan cycle number. must be >= 1. default: from last mtrx_open_file call.
+
+
+
Returns
reference of the newly created or existing data folder.
+ +

Definition at line 405 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_load_all()

+ +
+
+ + + + + + + +
variable mtrx_load_all ()
+
+ +

load all data from a Matrix data file.

+ +

Definition at line 231 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_load_file()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
string mtrx_load_file (string pathName,
string fileName,
string traces = defaultValue 
)
+
+ +

load all data from a Matrix data file.

+

the data wave is loaded into a sub-subfolder the current data folder. the relative path has the format ":mtrx_{date}_{time}:r{run_cycle}s{scan_cycle}", where the parameters {date}, {time}, {run_cycle} and {scan_cycle} are copied from the file name. the file name must be formatted according to the specifications set out below.

+
Parameters
+ + + + +
pathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
fileNameif empty a dialog box shows up the file name must adhere to the format "{prefix}-{date}-{time}-{anything}--{run_cycle}_{scan_cycle}.{extension}". the first three seperators can alternatively be underscores. it may be necessary to change the configuration of the Matrix application.
traces(currently not used) semicolon-separated list of preferred traces. the items of the list are match strings for the Igor StringMatch function. only matching traces are loaded from the file. default: "*Up;*Down;*ReUp;*ReDown;"
+
+
+
Returns
semicolon-separated list of loaded waves including partial path from current data folder.
+ +

Definition at line 767 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_load_info()

+ +
+
+ + + + + + + + + + + + + + + + + + +
string mtrx_load_info (string APathName,
string AFileName 
)
+
+ +

load descriptive info from a Matrix data file.

+

the info string lists the following information for each scan contained in the file:

    +
  • path of the scan group inside the file.
  • +
  • number of scan positions.
  • +
  • dataset names of scan positioners.
  • +
  • dataset names of detectors.
  • +
+
Parameters
+ + + +
APathNameigor symbolic path name. can be empty if the path is specified in AFileName or a dialog box should be displayed
AFileNameif empty a dialog box shows up
+
+
+
Returns
newline terminated string.
+ +

Definition at line 863 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_load_preview()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string mtrx_load_preview (string destName,
string pathName,
string fileName,
string traces = defaultValue 
)
+
+ +

load a preview image from a Matrix data file.

+

the data wave is loaded into the current data folder.

+
Parameters
+ + + + + +
destNamedestination wave name. the wave is created in the current data folder.
pathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
fileNameif empty a dialog box shows up the file name must adhere to the format "{prefix}-{date}-{time}-{anything}--{run_cycle}_{scan_cycle}.{extension}". the first three seperators can alternatively be underscores. it may be necessary to change the configuration of the Matrix application.
traces(currently not used) semicolon-separated list of preferred traces. the items of the list are match strings for the Igor StringMatch function. only the first matching trace is loaded from the file. default: "*Up;*Down;*ReUp;*ReDown;"
+
+
+
Returns
semicolon-separated list of loaded waves including partial path from current data folder.
+ +

Definition at line 682 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_open_file()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable mtrx_open_file (string pathName,
string fileNameOrPath 
)
+
+ +

open a matrix result or data file

+

this function opens a matrix result file (.mtrx) or data file (.*_mtrx).

+

if a data file is selected, the function locates the corresponding result file, opens it, and looks up the bricklet ID of the data file. if a result file is selected, the function opens it but does not look up bricklet IDs.

+

the result file remains open and can be accessed using the mtrx_ functions or MFR_ operations. once a result file is open, you can easily access any bricklets linked to it, i.e., any run cycle, scan cycle, and channel.

+

the function stores information about the opened file in a global package data folder. if the same result file is opened again later, the information is reused and the file not read again. this may cause problems if the file has been modified in the meantime, or if the cached data become corrupt for some reason. the function detects if a data file is not linked in the open result file, and updates the cache. in other situations it may be necessary to force a reload.

+
Todo:
fix possible cache issues, add an option to override the cache.
+
Parameters
+ + + +
pathNameigor path name or empty string.
fileNamefile name, with or without path, or empty string.
+
+
+
Returns
file type
    +
  • 0 result file (logbook)
  • +
  • 1 result data file (bricklet)
  • +
  • -1 error, no data loaded
  • +
  • -2 matrixfilereader.xop not installed
  • +
+
+ +

Definition at line 545 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_parse_filename()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable mtrx_parse_filename (string fileName,
string * resultFile,
variable * runCycle,
variable * scanCycle,
string * channel 
)
+
+ +

parse matrix file names

+

parse matrix file names for result name, run cycle, scan cycle, and channel.

+
Parameters
+ + + + + + +
fileNamematrix result or data file name (without path).
resultFile(out) base name of the result file. append "_%04u.mtrx" to get the actual result file. we do not know the chain link number at this stage.
runCycle(out) run cycle number. necessary to look up the bricklet ID.
scanCycle(out) scan cycle number. necessary to look up the bricklet ID.
channel(out) channel name.
+
+
+
Returns
file type
    +
  • 0 result file (logbook)
  • +
  • 1 result data file (bricklet)
  • +
+result file names look like: default_2015Apr20-124353_STM-STM_AtomManipulation_0001.mtrx, default_2015Apr20-124353_STM-STM_AtomManipulation_0002.mtrx, etc. the function returns the first part up to the experiment name ("AtomManipulation" in the examples). all other return values set to defaults and must not be regarded.
+

result data files look like: default_2015Apr20-124353_STM-STM_AtomManipulation–136_1.Aux1(V)_mtrx, default_2015Apr20-124353_STM-STM_AtomManipulation–136_1.I(V)_mtrx, default_2015Apr20-124353_STM-STM_AtomManipulation–14_1.I_mtrx, default_2015Apr20-124353_STM-STM_AtomManipulation–14_1.Z_mtrx, etc. the function returns all results as described in the parameter list.

+ +

Definition at line 294 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_scale_dataset()

+ +
+
+ + + + + + + + +
variable mtrx_scale_dataset (wave data)
+
+ +

Definition at line 829 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ mtrx_split_filename()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string mtrx_split_filename (string fileName,
string * prefix,
string * datepart,
string * timepart 
)
+
+ +

split a matrix filename and return the first three parts

+

we assume that the second (third) part contains the date (time). the parts are separated by dash or underscore.

+ +

Definition at line 332 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ preview_matrix_file()

+ +
+
+ + + + + +
+ + + + + + + + +
static wave preview_matrix_file (string filename)
+
+static
+
+ +

load the preview of a Matrix data file

+

the preview is loaded to the preview_image wave in the pearl_explorer data folder.

+

the s_file_info string is updated with information about the scan dimensions.

+
Parameters
+ + +
filenamename of a file in the directory specified by the pearl_explorer_filepath path object.
+
+
+
Returns
wave reference of the preview image
+ +

Definition at line 170 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ subtract_line_bg()

+ +
+
+ + + + + + + + +
variable subtract_line_bg (wave img)
+
+ +

remove linear background line-by-line

+ +

Definition at line 886 of file pearl-matrix-import.ipf.

+ +
+
+

Variable Documentation

+ +

◆ ks_filematch_mtrx

+ +
+
+ + + + + +
+ + + + +
const string ks_filematch_mtrx = "*_mtrx"
+
+static
+
+ +

Definition at line 40 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ package_name

+ +
+
+ + + + + +
+ + + + +
const string package_name = "pearl_matrix_import"
+
+static
+
+ +

Definition at line 37 of file pearl-matrix-import.ipf.

+ +
+
+ +

◆ package_path

+ +
+
+ + + + + +
+ + + + +
const string package_path = "root:packages:pearl_matrix_import:"
+
+static
+
+ +

Definition at line 38 of file pearl-matrix-import.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=3
2 #pragma version = 1.00
3 #pragma IgorVersion = 6.36
4 #pragma ModuleName = PearlMatrixImport
5 
6 // author: matthias.muntwiler@psi.ch
7 // Copyright (c) 2016 Paul Scherrer Institut
8 
9 // Licensed under the Apache License, Version 2.0 (the "License");
10 // you may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at
12 // http://www.apache.org/licenses/LICENSE-2.0
13 
31 
36 
37 static strconstant package_name = "pearl_matrix_import"
38 static strconstant package_path = "root:packages:pearl_matrix_import:"
39 
40 static strconstant ks_filematch_mtrx = "*_mtrx"
41 
45 static function init_package()
46 
47  dfref savedf = getdatafolderdfr()
48 
49  setdatafolder root:
50  newdatafolder /o/s packages
51  newdatafolder /o/s $package_name
52 
53  variable /g loglevel = 3
54  string /g dataFilePath = ""
55  string /g resultFilePath = ""
56  variable /g runCycle = 0
57  variable /g scanCycle = 0
58  string /g channelName = ""
59  variable /g brickletID = 0
60  variable /g V_MatrixFileReaderOverwrite = 1
61  variable /g V_MatrixFileReaderFolder = 0
62  variable /g V_MatrixFileReaderDouble = 0
63 
64  setdatafolder savedf
65  return 0
66 end
67 
72 static function check_package_folder()
73  dfref df_pack = $(package_path)
74  if (DataFolderRefStatus(df_pack))
75  svar /sdfr=df_pack /z resultFilePath
76  if (!svar_exists(resultFilePath))
77  init_package()
78  endif
79  else
80  init_package()
81  endif
82 end
83 
85 static function AfterFileOpenHook(refNum,file,pathName,type,creator,kind)
86  Variable refNum,kind
87  String file,pathName,type,creator
88  if( (kind >= 1) && (kind <= 2))
89  init_package()
90  //load_prefs()
91  endif
92  return 0
93 end
94 
102 static function BeforeFileOpenHook(refNum,fileName,path,type,creator,kind)
103  Variable refNum,kind
104  String fileName,path,type,creator
105 
106  Variable handledOpen = 0
107  if (StringMatch(fileName, ks_filematch_mtrx))
108  setdatafolder root:
109  newdatafolder /o /s matrix
110  mtrx_load_preview("matrix", path, fileName)
111  handledOpen = 1
112  endif
113  return handledOpen
114 End
115 
120 function /s matrix_format_elog_message(metadata)
121  wave /t metadata
122 
123  string key
124  string value
125  variable nkeys = dimsize(metadata, 0)
126  variable ikey
127  string message_keys
128  message_keys = "resultFileName;sampleName;channelName;"
129  message_keys += "XYScanner.Points.value;XYScanner.Raster_Time.value;XYScanner.Raster_Time.unit;XYScanner.Width.value;XYScanner.Width.unit;XYScanner.Height.value;XYScanner.Height.unit;"
130  message_keys += "GapVoltageControl.Voltage.value;GapVoltageControl.Voltage.unit;"
131  message_keys += "Regulator.Loop_Gain_1_I.value;Regulator.Loop_Gain_1_I.unit;Regulator.Setpoint_1.value;Regulator.Setpoint_1.unit;"
132  message_keys += "Spectroscopy.Device_1_Start.value;Spectroscopy.Device_1_Start.unit;Spectroscopy.Spectroscopy_Mode.value;"
133  string message
134 
135  message_keys = ""
136  for (ikey = 0; ikey < nkeys; ikey += 1)
137  key = metadata[ikey][0]
138  value = metadata[ikey][1]
139  if (WhichListItem(key, message_keys) >= 0)
140  message += key + " = " + value + "\r"
141  endif
142  endfor
143 end
144 
145 function matrix_preview_2d(data, metadata)
146  wave data
147  wave /t metadata
148 
149  Display
150  AppendImage data
151  ModifyImage data ctab= {*,*,Mud,0}
152  ModifyGraph margin(left)=30,margin(bottom)=30,margin(top)=5,margin(right)=5,height={Plan,1,left,bottom}
153  ModifyGraph mirror=2
154  ModifyGraph nticks=3
155  ModifyGraph axThick=0.5
156  ModifyGraph btLen=4
157 
158 end
159 
170 static function /wave preview_matrix_file(filename)
171  string filename
172 
173  dfref saveDF = GetDataFolderDFR()
174  setdatafolder $package_path
175  svar s_preview_file
176  svar s_preview_source
177  mtrx_load_preview("preview_image", "pearl_explorer_filepath", filename)
178  s_preview_file = filename
179  s_preview_source = ""
180  wave /z preview_image
181 
182  svar /z s_file_info
183  if (! svar_exists(s_file_info))
184  string /g s_file_info
185  endif
186  if (strlen(s_preview_file) > 0)
187  s_file_info = mtrx_load_info("pearl_explorer_filepath", filename)
188  else
189  s_file_info = ""
190  endif
191 
192  setdatafolder saveDF
193  return preview_image
194 end
195 
197 Structure errorCode
198  int32 SUCCESS
199  int32 UNKNOWN_ERROR
200  int32 ALREADY_FILE_OPEN
201  int32 EMPTY_RESULTFILE
202  int32 FILE_NOT_READABLE
203  int32 NO_NEW_BRICKLETS
204  int32 WRONG_PARAMETER
205  int32 INTERNAL_ERROR_CONVERTING_DATA
206  int32 NO_FILE_OPEN
207  int32 INVALID_RANGE
208  int32 WAVE_EXIST
209 EndStructure
210 
212 static Function initStruct(errorCode)
213  Struct errorCode &errorCode
214 
215  errorCode.SUCCESS =0
216  errorCode.UNKNOWN_ERROR=10001
217  errorCode.ALREADY_FILE_OPEN=10002
218  errorCode.EMPTY_RESULTFILE=10004
219  errorCode.FILE_NOT_READABLE=10008
220  errorCode.NO_NEW_BRICKLETS=10016
221  errorCode.WRONG_PARAMETER=10032
222  errorCode.INTERNAL_ERROR_CONVERTING_DATA=10064
223  errorCode.NO_FILE_OPEN=10128
224  errorCode.INVALID_RANGE=10256
225  errorCode.WAVE_EXIST=10512
226 
227 end
228 
231 function mtrx_load_all()
232 
233  struct errorCode errorCode
234  initStruct(errorCode)
235 
236 #if exists("MFR_OpenResultFile")
237  MFR_OpenResultFile
238  if(V_flag != errorCode.SUCCESS)
239  MFR_GetXOPErrorMessage
240  return -1
241  endif
242 
243  MFR_GetBrickletData
244  if(V_flag != errorCode.SUCCESS)
245  MFR_GetXOPErrorMessage
246  return -1
247  endif
248 
249  MFR_GetBrickletMetaData
250  if(V_flag != errorCode.SUCCESS)
251  MFR_GetXOPErrorMessage
252  return -1
253  endif
254 
255  return 0
256 #else
257  return -1
258 #endif
259 end
260 
294 function mtrx_parse_filename(fileName, resultFile, runCycle, scanCycle, channel)
295  string fileName
296  string &resultFile
297  variable &runCycle
298  variable &scanCycle
299  string &channel
300 
301  variable fileType = 0
302  resultFile = ""
303  channel = ""
304  runCycle = 0
305  scanCycle = 0
306 
307  string regexp = ""
308  string index1 = ""
309  string index2 = ""
310  string extension = ""
311 
312  if (StringMatch(fileName, "*.mtrx"))
313  regexp = "(.+)_([[:digit:]]+)\.(.+)"
314  SplitString /E=regexp fileName, resultFile, index1, extension
315  fileType = 0
316  else
317  regexp = "(.+)--([[:digit:]]+)_([[:digit:]]+)\.((.+)_mtrx)"
318  SplitString /E=regexp fileName, resultFile, index1, index2, extension, channel
319  fileType = 1
320  runCycle = str2num(index1)
321  scanCycle = str2num(index2)
322  endif
323 
324  return fileType
325 end
326 
332 function /s mtrx_split_filename(fileName, prefix, datepart, timepart)
333  string fileName
334  string &prefix
335  string &datepart
336  string &timepart
337 
338  string regexp
339  regexp = "([[:alpha:][:digit:]]+)[-_]([[:alpha:][:digit:]]+)[-_]([[:alpha:][:digit:]]+)[-_].+"
340  SplitString /E=regexp fileName, prefix, datepart, timepart
341  return datepart
342 end
343 
360 function /df mtrx_create_folder(fileName, [df_base])
361  string fileName
362  dfref df_base
363 
364  if (ParamIsDefault(df_base))
365  df_base = GetDataFolderDFR()
366  endif
367 
368  string prefix
369  string datepart
370  string timepart
371  string folderName
372 
373  mtrx_split_filename(fileName, prefix, datepart, timepart)
374  folderName = "mtrx_" + datepart + "_" + timepart
375  folderName = CleanupName(folderName, 0)
376 
377  dfref df_save = GetDataFolderDFR()
378  setdatafolder root:
379  newdatafolder /o /s $foldername
380  dfref df = GetDataFolderDFR()
381 
382  setdatafolder df_save
383  return df
384 end
385 
405 function /df mtrx_get_cycle_folder([df_base, runCycle, scanCycle])
406  dfref df_base
407  variable runCycle
408  variable scanCycle
409 
410  dfref df_save = GetDataFolderDFR()
411  dfref df_pack = $(package_path)
412  if (ParamIsDefault(df_base))
413  df_base = GetDataFolderDFR()
414  endif
415  if (ParamIsDefault(runCycle))
416  nvar /sdfr=df_pack defRunCycle = runCycle
417  runCycle = defRunCycle
418  endif
419  if (ParamIsDefault(scanCycle))
420  nvar /sdfr=df_pack defScanCycle = scanCycle
421  scanCycle = defScanCycle
422  endif
423 
424  string dfname
425  if ((runCycle >= 1) && (scanCycle >= 1))
426  sprintf dfname, "r%us%u", runCycle, scanCycle
427  setdatafolder df_base
428  dfref df = $dfname
429  if (DataFolderRefStatus(df) == 0)
430  newdatafolder $dfname
431  dfref df = $dfname
432  endif
433  else
434  dfref df = df_base
435  endif
436 
437  setdatafolder df_save
438  return df
439 end
440 
461 function mtrx_file_brickletID(resultFile, runCycle, scanCycle, channel)
462  string resultFile
463  variable runCycle
464  variable scanCycle
465  string channel
466 
467  dfref df_overview = NewFreeDataFolder()
468  variable link = 1
469  variable id = -1
470  variable idx = 0
471 
472  string resultFileName
473 #if exists("MFR_OpenResultFile")
474  struct errorCode errorCode
475  initStruct(errorCode)
476  do
477  sprintf resultFileName, "%s_%04u.mtrx", resultFile, link
478  MFR_OpenResultFile /K resultFileName
479  if(V_flag != errorCode.SUCCESS)
480  return -1
481  endif
482  MFR_CreateOverviewTable /DEST=df_overview
483  // dimension labels are: brickletID, scanCycleCount, runCycleCount, sequenceID, dimension, channelName
484  wave /t /sdfr=df_overview overviewTable
485  make /n=(dimsize(overviewTable, 0)) /i /u /free runcycles, scancycles, ids, match
486  make /n=(dimsize(overviewTable, 0)) /t /free channels
487  ids = str2num(overviewtable[p][%brickletID])
488  if (runcycle > 0)
489  runcycles = str2num(overviewtable[p][%runCycleCount])
490  else
491  runcycles = runcycle
492  endif
493  if (scancycle > 0)
494  scancycles = str2num(overviewtable[p][%scanCycleCount])
495  else
496  scancycles = scancycle
497  endif
498  if (strlen(channel) > 0)
499  channels = overviewTable[p][%channelName]
500  else
501  channels = channel
502  endif
503  Extract /FREE ids, match_ids, (scancycles == scanCycle) && (runcycles == runCycle) && (cmpstr(channels, channel) == 0)
504  if (numpnts(match_ids) > 0)
505  id = match_ids[0]
506  else
507  link += 1
508  endif
509  while (id < 0)
510 #endif
511  return id
512 end
513 
545 function mtrx_open_file(pathName, fileNameOrPath)
546  string pathName
547  string fileNameOrPath
548 
549  check_package_folder()
550  dfref df_save = GetDataFolderDFR()
551  dfref df_pack = $(package_path)
552  svar /sdfr=df_pack dataFilePath
553  svar /sdfr=df_pack resultFilePath
554  nvar /sdfr=df_pack runCycle
555  nvar /sdfr=df_pack scanCycle
556  svar /sdfr=df_pack channelName
557  nvar /sdfr=df_pack brickletID
558 
559  string loc_resultFileName
560  string loc_resultFilePath
561  variable loc_runCycle
562  variable loc_scanCycle
563  string loc_channelName
564 
565  // make sure we have a valid and complete file path
566  GetFileFolderInfo /P=$pathName /Q /Z=2 fileNameOrPath
567  string filePath
568  if ((v_flag == 0) && (v_isFile))
569  filePath = s_path
570  else
571  return -1
572  endif
573 
574  // get base file name
575  string fileName
576  string fileDir
577  string baseFileName
578  variable fileType
579  fileName = ParseFilePath(0, filePath, ":", 1, 0)
580  fileDir = ParseFilePath(1, filePath, ":", 1, 0)
581  fileType = mtrx_parse_filename(fileName, baseFileName, loc_runCycle, loc_scanCycle, loc_channelName)
582 
583  variable link = 1
584  variable id = -1
585  variable result = -1
586  variable using_cache = 0
587 
588  struct errorCode errorCode
589  initStruct(errorCode)
590  do
591  sprintf loc_resultFileName, "%s_%04u.mtrx", baseFileName, link
592  loc_resultFilePath = fileDir + loc_resultFileName
593 #if exists("MFR_OpenResultFile")
594  if ((strlen(resultFilePath) == 0) || (cmpstr(loc_resultFilePath, resultFilePath) != 0))
595  MFR_OpenResultFile /K loc_resultFilePath
596  if(V_flag != errorCode.SUCCESS)
597  MFR_GetXOPErrorMessage
598  result = -1
599  break
600  endif
601  resultFilePath = loc_resultFilePath
602  if (fileType == 1)
603  dataFilePath = filePath
604  else
605  dataFilePath = ""
606  endif
607  runCycle = 0
608  scanCycle = 0
609  channelName = ""
610  brickletID = 0
611  MFR_CreateOverviewTable /DEST=df_pack
612  if(V_flag != errorCode.SUCCESS)
613  MFR_GetXOPErrorMessage
614  result = -1
615  break
616  endif
617  using_cache = 0
618  else
619  using_cache = 1
620  endif
621 #else
622  print "matrixfilereader.xop not installed"
623  result = -2
624  break
625 #endif
626  // dimension labels are: brickletID, scanCycleCount, runCycleCount, sequenceID, dimension, channelName
627  wave /t /sdfr=df_pack overviewTable
628  make /n=(dimsize(overviewTable, 0)) /i /u /o df_pack:runCycles, df_pack:scanCycles, df_pack:ids
629  make /n=(dimsize(overviewTable, 0)) /t /o df_pack:channels
630  wave /sdfr=df_pack ids, runCycles, scanCycles
631  wave /t /sdfr=df_pack channels
632  ids = str2num(overviewtable[p][%brickletID])
633  runCycles = str2num(overviewtable[p][%runCycleCount])
634  scanCycles = str2num(overviewtable[p][%scanCycleCount])
635  channels = overviewTable[p][%channelName]
636  result = fileType
637 
638  // if a data file is opened, make sure we found the right result file
639  if ((loc_runCycle > 0) && (loc_scanCycle > 0))
640  Extract /FREE ids, match_ids, (runCycles == loc_runCycle) && (scanCycles == loc_scanCycle) && (cmpstr(channels, loc_channelName) == 0)
641  if (numpnts(match_ids) > 0)
642  id = match_ids[0]
643  runCycle = loc_runCycle
644  scanCycle = loc_scanCycle
645  channelName = loc_channelName
646  brickletID = id
647  break
648  elseif (using_cache)
649  resultFilePath = ""
650  else
651  link += 1
652  endif
653  else
654  break
655  endif
656  while (id < 0)
657 
658  return result
659 end
660 
682 function /s mtrx_load_preview(destName, pathName, fileName, [traces])
683  string destName
684  string pathName
685  string fileName
686  string traces
687 
688  if (ParamIsDefault(traces))
689  traces = "*Up;*Down;*ReUp;*ReDown;"
690  endif
691 
692  dfref df_save = GetDataFolderDFR()
693 
694  string datanames = ""
695  string datapaths = ""
696  variable filestatus = mtrx_open_file(pathName, fileName)
697  if (filestatus != 1)
698  return ""
699  endif
700 
701  dfref df_pack = $(package_path)
702  svar /sdfr=df_pack dataFilePath
703  svar /sdfr=df_pack resultFilePath
704  nvar /sdfr=df_pack runCycle
705  nvar /sdfr=df_pack scanCycle
706  svar /sdfr=df_pack channelName
707  nvar /sdfr=df_pack brickletID
708 
709 #if exists("MFR_OpenResultFile")
710  dfref df_data = df_save
711  variable /g df_data:V_MatrixFileReaderOverwrite = 1
712  variable /g df_data:V_MatrixFileReaderFolder = 0
713  variable /g df_data:V_MatrixFileReaderDouble = 0
714  struct errorCode errorCode
715  initStruct(errorCode)
716  MFR_GetBrickletData /N=destName /R=(brickletID) /S=2 /DEST=df_data
717  if(V_flag == errorCode.SUCCESS)
718  datanames = S_waveNames
719  variable i
720  variable n = ItemsInList(datanames)
721  string s
722  s = StringFromList(0, datanames)
723  wave data = $s
724  mtrx_scale_dataset(data)
725  if (WaveDims(data) == 2)
726  subtract_line_bg(data)
727  endif
728  datapaths = AddListItem(GetWavesDataFolder(data, 4), datapaths, ";", inf)
729  for (i = 1; i < n; i += 1)
730  s = StringFromList(i, datanames)
731  killwaves /z $s
732  endfor
733  else
734  MFR_GetXOPErrorMessage
735  endif
736  //MFR_GetBrickletMetaData /N=ANickName /R=(brickletID) // /DEST=dfref
737 #else
738  print "matrixfilereader.xop not installed"
739 #endif
740 
741  setdatafolder df_save
742  return datapaths
743 end
744 
767 function /s mtrx_load_file(pathName, fileName, [traces])
768  string pathName
769  string fileName
770  string traces
771 
772  if (ParamIsDefault(traces))
773  traces = "*Up;*Down;*ReUp;*ReDown;"
774  endif
775 
776  dfref df_save = GetDataFolderDFR()
777 
778  string datanames = ""
779  string datapaths = ""
780  variable filestatus = mtrx_open_file(pathName, fileName)
781  if (filestatus != 1)
782  return ""
783  endif
784 
785  dfref df_pack = $(package_path)
786  svar /sdfr=df_pack dataFilePath
787  svar /sdfr=df_pack resultFilePath
788  nvar /sdfr=df_pack runCycle
789  nvar /sdfr=df_pack scanCycle
790  svar /sdfr=df_pack channelName
791  nvar /sdfr=df_pack brickletID
792 
793 #if exists("MFR_OpenResultFile")
794  string resultFileName = ParseFilePath(0, resultFilePath, ":", 1, 0)
795  dfref df_result = mtrx_create_folder(resultFileName, df_base=df_save)
796  dfref df_data = mtrx_get_cycle_folder(df_base = df_result)
797  variable /g df_data:V_MatrixFileReaderOverwrite = 1
798  variable /g df_data:V_MatrixFileReaderFolder = 0
799  variable /g df_data:V_MatrixFileReaderDouble = 0
800 
801  struct errorCode errorCode
802  initStruct(errorCode)
803  string name
804  name = CleanupName(channelName, 0)
805  MFR_GetBrickletData /N=name /R=(brickletID) /DEST=df_data
806  if(V_flag == errorCode.SUCCESS)
807  datanames = S_waveNames
808  variable i
809  variable n = ItemsInList(datanames)
810  string s
811  for (i = 0; i < n; i += 1)
812  s = StringFromList(i, datanames)
813  wave /sdfr=df_data data = $s
814  mtrx_scale_dataset(data)
815  datapaths = AddListItem(GetWavesDataFolder(data, 4), datapaths, ";", inf)
816  endfor
817  else
818  MFR_GetXOPErrorMessage
819  endif
820  //MFR_GetBrickletMetaData /N=ANickName /R=(brickletID) // /DEST=dfref
821 #else
822  print "matrixfilereader.xop not installed"
823 #endif
824 
825  setdatafolder df_save
826  return datapaths
827 end
828 
829 function mtrx_scale_dataset(data)
830  wave data
831 
832  dfref df_pack = $(package_path)
833  nvar /sdfr=df_pack runCycle
834  nvar /sdfr=df_pack scanCycle
835  svar /sdfr=df_pack channelName
836  nvar /sdfr=df_pack brickletID
837 
838  string scanDir = StringFromList(2, NameOfWave(data), "_")
839  if (WaveDims(data) == 2)
840  Note data, "AxisLabelX=X"
841  Note data, "AxisLabelY=Y"
842  endif
843  Note data, "AxisLabelD=" + channelName
844  string title
845  sprintf title, "%u-%u %s %s", runCycle, scanCycle, channelName, scanDir
846  Note data, "Dataset=" + title
847 end
848 
863 function /s mtrx_load_info(APathName, AFileName)
864  string APathName
865  string AFileName
866 
867  dfref saveDF = GetDataFolderDFR()
868  dfref fileDF = NewFreeDataFolder()
869  setdatafolder fileDF
870 
871  variable fileID
872  string filepath
873  string scanpaths
874  variable nscans
875  variable iscan
876  string scanpath
877  string info = ""
878 
879 
880  setdatafolder saveDF
881  return info
882 end
883 
886 function subtract_line_bg(img)
887  wave img
888 
889  variable nx = dimsize(img, 0)
890  variable ny = dimsize(img, 1)
891  variable iy
892  make /n=(nx) /free line, fit
893  for (iy = 0; iy < ny; iy += 1)
894  line = img[p][iy]
895  if (numtype(sum(line)) == 0)
896  CurveFit /N /Q /NTHR=0 line line /D=fit
897  img[][iy] = line[p] - fit[p]
898  endif
899  endfor
900 end
static const string package_path
+
dfr mtrx_create_folder(string fileName, dfref df_base=defaultValue)
create or look up a data folder based on a matrix file name.
+
variable mtrx_file_brickletID(string resultFile, variable runCycle, variable scanCycle, string channel)
find out bricklet ID of a file
+
static variable initStruct(errorCode *errorCode)
from matrixfilereader help
+
string mtrx_split_filename(string fileName, string *prefix, string *datepart, string *timepart)
split a matrix filename and return the first three parts
+
variable matrix_preview_2d(wave data, wave metadata)
+
static wave preview_matrix_file(string filename)
load the preview of a Matrix data file
+
string mtrx_load_info(string APathName, string AFileName)
load descriptive info from a Matrix data file.
+
string matrix_format_elog_message(wave metadata)
generate elog message from bricklet metadata
+
from matrixfilereader help
+
variable mtrx_load_all()
load all data from a Matrix data file.
+
int32 SUCCESS
+
static const string ks_filematch_mtrx
+
static variable AfterFileOpenHook(variable refNum, string file, string pathName, string type, string creator, variable kind)
initialize the package and reload preferences after an experiment is loaded.
+
dfr mtrx_get_cycle_folder(dfref df_base=defaultValue, variable runCycle=defaultValue, variable scanCycle=defaultValue)
create a data folder for bricklet data.
+
static variable init_package()
initialize the package data folder.
+
variable mtrx_parse_filename(string fileName, string *resultFile, variable *runCycle, variable *scanCycle, string *channel)
parse matrix file names
+
string mtrx_load_preview(string destName, string pathName, string fileName, string traces=defaultValue)
load a preview image from a Matrix data file.
+
static variable BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind)
open a matrix file that was dropped into Igor.
+
static const string package_name
+
static variable check_package_folder()
check that the package data folder exists
+
+
+Functions
pearl-menu.ipf File Reference

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + +

+Functions

string PearlMenuEnableFunc (string funcname)
 
variable LoadPearlOptics ()
 
variable LoadPearlArpes ()
 
variable LoadPearlPreparation ()
 
variable Display2dProfiles ()
 
variable Display3dSlicer ()
 
variable DisplayGizmoSlicer ()
 
variable PearlLiveDisplay (string epicsname, string nickname, string wbRGB)
 
variable PearlAnglescanTracker (string epicsname, string wbRGB)
 
+

Function Documentation

+ +

◆ Display2dProfiles()

+ +
+
+ + + + + + + +
variable Display2dProfiles ()
+
+ +

Definition at line 113 of file pearl-menu.ipf.

+ +
+
+ +

◆ Display3dSlicer()

+ +
+
+ + + + + + + +
variable Display3dSlicer ()
+
+ +

Definition at line 130 of file pearl-menu.ipf.

+ +
+
+ +

◆ DisplayGizmoSlicer()

+ +
+
+ + + + + + + +
variable DisplayGizmoSlicer ()
+
+ +

Definition at line 149 of file pearl-menu.ipf.

+ +
+
+ +

◆ LoadPearlArpes()

+ +
+
+ + + + + + + +
variable LoadPearlArpes ()
+
+ +

Definition at line 101 of file pearl-menu.ipf.

+ +
+
+ +

◆ LoadPearlOptics()

+ +
+
+ + + + + + + +
variable LoadPearlOptics ()
+
+ +

Definition at line 94 of file pearl-menu.ipf.

+ +
+
+ +

◆ LoadPearlPreparation()

+ +
+
+ + + + + + + +
variable LoadPearlPreparation ()
+
+ +

Definition at line 107 of file pearl-menu.ipf.

+ +
+
+ +

◆ PearlAnglescanTracker()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable PearlAnglescanTracker (string epicsname,
string wbRGB 
)
+
+ +

Definition at line 187 of file pearl-menu.ipf.

+ +
+
+ +

◆ PearlLiveDisplay()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
variable PearlLiveDisplay (string epicsname,
string nickname,
string wbRGB 
)
+
+ +

Definition at line 168 of file pearl-menu.ipf.

+ +
+
+ +

◆ PearlMenuEnableFunc()

+ +
+
+ + + + + + + + +
string PearlMenuEnableFunc (string funcname)
+
+ +

Definition at line 82 of file pearl-menu.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=1 // Use modern global access method.
2 #pragma ModuleName = PearlMenu
3 #pragma version = 1.02
4 
5 // main menu for PEARL data acquisition and analysis packages
6 
7 // $Id$
8 // author: matthias.muntwiler@psi.ch
9 // Copyright (c) 2013-14 Paul Scherrer Institut
10 
11 // Licensed under the Apache License, Version 2.0 (the "License");
12 // you may not use this file except in compliance with the License.
13 // You may obtain a copy of the License at
14 // http://www.apache.org/licenses/LICENSE-2.0
15 
16 menu "PEARL"
17 
18  submenu "Data Files"
19  PearlMenuEnableFunc("pearl_data_explorer") + "Data Explorer", /Q, pearl_data_explorer()
20  help = {"Data explorer panel with file import and preview", "Requires ARPES package and HDF5 XOP"}
21  PearlMenuEnableFunc("ad_load_dialog") + "AD HDF5", /Q, ad_load_dialog("")
22  help = {"Import area detector HDF5 data file", "Requires ARPES package and HDF5 XOP"}
23  end
24 
25  submenu "On-the-Fly Data"
26  PearlMenuEnableFunc("otf_rename_folders") + "Shorten OTF Folder Names", /Q, otf_rename_folders("010")
27  help = {"Renames otf_xxxxxx_yyyyyy_zzzz data folders to otf_yyyyyy (removing date and suffix)", "Requires Optics package"}
28  PearlMenuEnableFunc("otf_gather_batch") + "Gather OTF Batch", /Q, otf_gather_batch("current_ch1", "photonenergy", "otf_batch")
29  help = {"Copies data from all otf_* folders into otf_batch folder", "Requires Optics package"}
30  PearlMenuEnableFunc("PearlOpticsPreviewPanel") + "OTF Preview", /Q, PearlOpticsPreviewPanel()
31  help = {"Opens a preview panel for OTF data in otf_* folders", "Requires Optics package"}
32  end
33 
34  submenu "Scienta Analyser"
35  PearlMenuEnableFunc("ad_display_profiles") + "Scienta Live View", /Q, PearlLiveDisplay("X03DA-SCIENTA:", "EA", "(65280,54528,48896)")
36  help = {"Display preview panel with latest image from Scienta", "Requires ARPES package and EPICS XOP"}
37  PearlMenuEnableFunc("ast_setup") + "Angle Scan Tracker", /Q, PearlAnglescanTracker("X03DA-SCIENTA:", "(65280,54528,48896)")
38  help = {"Preview of acquired angle scan data and current detection angles.", "Requires ARPES package and EPICS XOP"}
39  end
40 
41  submenu "Cameras"
42  PearlMenuEnableFunc("ad_display_profiles") + "Exit Slit Live View", /Q, PearlLiveDisplay("X03DA-OP-PS1:", "OP", "(65280,54528,48896)")
43  help = {"Display preview panel with latest image from Scienta", "Requires ARPES package and EPICS XOP"}
44  PearlMenuEnableFunc("ad_display_profiles") + "Manipulator Live View", /Q, PearlLiveDisplay("X03DA-ES-PS1:", "ES", "(65280,54528,48896)")
45  help = {"Display live panel of the exit slit camera", "Requires ARPES package and EPICS XOP"}
46  end
47 
48  submenu "Display"
49  PearlMenuEnableFunc("ad_display_profiles") + "2D Profiles", /Q, Display2dProfiles()
50  help = {"Profiles display of 2D data", "Requires ARPES package"}
51  PearlMenuEnableFunc("ad_display_brick") + "3D Slicer", /Q, Display3dSlicer()
52  help = {"Slice and profiles display of 3D data", "Requires ARPES package"}
53  PearlMenuEnableFunc("ad_display_brick") + "3D Gizmo", /Q, DisplayGizmoSlicer()
54  help = {"Gizmo display of 3D data", "Requires ARPES package"}
55  end
56 
57  submenu "Process"
58  PearlMenuEnableFunc("asp_show_panel") + "XPD scans", /Q, asp_show_panel()
59  help = {"Data processing of two-pi angle scans", "Requires ARPES package"}
60  end
61 
62  submenu "Services"
63  PearlMenuEnableFunc("pearl_elog") + "Open ELOG Panel", /Q, pearl_elog("")
64  help = {"Open an ELOG panel to send entries to an ELOG logbook"}
65  end
66 
67  submenu "Sample Preparation"
68  PearlMenuEnableFunc("ann_ramp_start") + "Annealing Ramp", /Q, panel_ramp_gen()
69  help = {"Sample annealing ramp generator"}
70  end
71 
72  submenu "Packages"
73  "Load ARPES Package", /Q, LoadPearlArpes()
74  help = {"Data processing and analysis for ARPES experiments"}
75  "Load Preparation Package", /Q, LoadPearlPreparation()
76  help = {"Process control for sample preparation"}
77  "Load Optics Package", /Q, LoadPearlOptics()
78  help = {"Data processing and analysis for beamline commissioning"}
79  end
80 end
81 
82 function /s PearlMenuEnableFunc(funcname)
83  // checks whether a function name exists
84  // and conditionally returns a prefix which disables the menu item
85  // if the function does not exist
86  string funcname
87  if (exists(funcname) >= 3)
88  return ""
89  else
90  return "("
91  endif
92 end
93 
94 function LoadPearlOptics()
95  execute /p/q/z "INSERTINCLUDE \"pearl-optics\""
96  execute /p/q/z "COMPILEPROCEDURES "
97  execute /p/q/z "PearlOpticsPanel#po_InitPanel()"
98  execute /p/q/z "BuildMenu \"PEARL\""
99 end
100 
101 function LoadPearlArpes()
102  execute /p/q/z "INSERTINCLUDE \"pearl-arpes\""
103  execute /p/q/z "COMPILEPROCEDURES "
104  execute /p/q/z "BuildMenu \"PEARL\""
105 end
106 
107 function LoadPearlPreparation()
108  execute /p/q/z "INSERTINCLUDE \"pearl-preparation\""
109  execute /p/q/z "COMPILEPROCEDURES "
110  execute /p/q/z "BuildMenu \"PEARL\""
111 end
112 
113 function Display2dProfiles()
114  dfref dfBefore = GetDataFolderDFR()
115  Execute /q/z "CreateBrowser prompt=\"Select 2D wave\", showWaves=1, showVars=0, showStrs=0"
116  dfref dfAfter = GetDataFolderDFR()
117  SetDataFolder dfBefore
118 
119  SVAR list = S_BrowserList
120  NVAR flag = V_Flag
121 
122  if ((flag != 0) && (ItemsInList(list) >= 1))
123  string brickname = StringFromList(0, list)
124  string cmd
125  sprintf cmd, "ad_display_profiles(%s)", brickname
126  execute /q/z cmd
127  endif
128 end
129 
130 function Display3dSlicer()
131  dfref dfBefore = GetDataFolderDFR()
132  Execute /q/z "CreateBrowser prompt=\"Select 3D wave\", showWaves=1, showVars=0, showStrs=0"
133  dfref dfAfter = GetDataFolderDFR()
134  SetDataFolder dfBefore
135 
136  SVAR list = S_BrowserList
137  NVAR flag = V_Flag
138 
139  if ((flag != 0) && (ItemsInList(list) >= 1))
140  string brickname = StringFromList(0, list)
141  string cmd
142  sprintf cmd, "ad_display_slice(%s)", brickname
143  execute /q/z cmd
144  sprintf cmd, "ad_brick_slicer(%s)", brickname
145  execute /q/z cmd
146  endif
147 end
148 
149 function DisplayGizmoSlicer()
150  dfref dfBefore = GetDataFolderDFR()
151  Execute /q/z "CreateBrowser prompt=\"Select 3D wave\", showWaves=1, showVars=0, showStrs=0"
152  dfref dfAfter = GetDataFolderDFR()
153  SetDataFolder dfBefore
154 
155  SVAR list = S_BrowserList
156  NVAR flag = V_Flag
157 
158  if ((flag != 0) && (ItemsInList(list) >= 1))
159  string brickname = StringFromList(0, list)
160  string cmd
161  sprintf cmd, "ad_display_brick(%s)", brickname
162  execute /q/z cmd
163  sprintf cmd, "ad_brick_slicer(%s)", brickname
164  execute /q/z cmd
165  endif
166 end
167 
168 function PearlLiveDisplay(epicsname, nickname, wbRGB)
169  string epicsname // base name of the detector, e.g. X03DA-SCIENTA:
170  // image1: and cam1: are appended by the function
171  // see ad_connect
172  string nickname // nick name under which this detector is referred to in Igor
173  // must be a valid data folder name
174  // see ad_connect
175  string wbRGB // window background color, e.g. "(32768,49152,55296)"
176  string cmd
177  sprintf cmd, "ad_connect(\"%s\", \"%s\")", epicsname, nickname
178  execute /q/z cmd
179  sprintf cmd, "ad_display_profiles(root:pearl_epics:%s:image)", nickname
180  execute /q/z cmd
181  sprintf cmd, "ModifyGraph wbRGB=%s", wbRGB
182  execute /q/z cmd
183  sprintf cmd, "add_roi_controls()"
184  execute /q/z cmd
185 end
186 
187 function PearlAnglescanTracker(epicsname, wbRGB)
188  string epicsname // base name of the detector, e.g. X03DA-SCIENTA:
189  // image1: and cam1: are appended by the function
190  // see ast_setup
191  string wbRGB // window background color, e.g. "(32768,49152,55296)"
192  string cmd
193  sprintf cmd, "ast_setup()"
194  execute /q/z cmd
195  sprintf cmd, "ModifyGraph wbRGB=%s", wbRGB
196  execute /q/z cmd
197 end
variable PearlLiveDisplay(string epicsname, string nickname, string wbRGB)
Definition: pearl-menu.ipf:168
+
variable DisplayGizmoSlicer()
Definition: pearl-menu.ipf:149
+
variable ad_load_dialog(string APathName)
load area detector data files selected in a file dialog window
+
variable ad_brick_slicer(wave data)
open a slicer panel for 3D data.
+
variable ast_setup()
set up data structures, display graph, and try to connect to analyser.
+
variable LoadPearlPreparation()
Definition: pearl-menu.ipf:107
+
variable PearlAnglescanTracker(string epicsname, string wbRGB)
Definition: pearl-menu.ipf:187
+
variable LoadPearlArpes()
Definition: pearl-menu.ipf:101
+
variable LoadPearlOptics()
Definition: pearl-menu.ipf:94
+
variable Display3dSlicer()
Definition: pearl-menu.ipf:130
+
variable otf_gather_batch(string ywavematch, string xwavematch, string destfolder)
+
variable asp_show_panel()
create the angle scan processing panel
+
variable otf_rename_folders(string pattern, variable unique_index=defaultValue, string new_suffix=defaultValue, string match_str=defaultValue)
+
string ad_display_profiles(wave image, string filter=defaultValue)
open a new profiles graph window.
+
variable pearl_data_explorer()
+
string PearlMenuEnableFunc(string funcname)
Definition: pearl-menu.ipf:82
+
string ad_display_slice(wave data)
display three-dimensional data by 2D slice.
+
variable pearl_elog(string logbook)
main function to initialize ELOG and to open an ELOG panel.
Definition: pearl-elog.ipf:97
+
string ad_display_brick(wave data)
open a new "gizmo" window with three-dimensional data.
+
variable Display2dProfiles()
Definition: pearl-menu.ipf:113
+
+
+Functions
pearl-otf-import.ipf File Reference

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + + + +

+Functions

variable otf_load_itx_all (string pathname)
 
variable otf_load_itx_match (string pathname, string matchstr)
 
variable otf_load_itx (string pathname, string filename)
 
variable otf_gather_iterator (dfref df, string *sdata)
 
variable otf_gather_batch (string ywavematch, string xwavematch, string destfolder)
 
variable gather_batch (string foldermatch, string ywavematch, string xwavematch, string destfolder)
 
variable otf_rename_folders_iterator (dfref df, string *sdata)
 
variable otf_rename_folders (string pattern, variable unique_index=defaultValue, string new_suffix=defaultValue, string match_str=defaultValue)
 
variable otf_interp (variable e1, variable e2, variable npts, variable smo)
 
variable otf_smo_int (wave win, wave wout, wave wpe, variable smo)
 
+

Function Documentation

+ +

◆ gather_batch()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable gather_batch (string foldermatch,
string ywavematch,
string xwavematch,
string destfolder 
)
+
+ +

Definition at line 162 of file pearl-otf-import.ipf.

+ +
+
+ +

◆ otf_gather_batch()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
variable otf_gather_batch (string ywavematch,
string xwavematch,
string destfolder 
)
+
+ +

Definition at line 152 of file pearl-otf-import.ipf.

+ +
+
+ +

◆ otf_gather_iterator()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable otf_gather_iterator (dfref df,
string * sdata 
)
+
+ +

Definition at line 106 of file pearl-otf-import.ipf.

+ +
+
+ +

◆ otf_interp()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable otf_interp (variable e1,
variable e2,
variable npts,
variable smo 
)
+
+ +

Definition at line 271 of file pearl-otf-import.ipf.

+ +
+
+ +

◆ otf_load_itx()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable otf_load_itx (string pathname,
string filename 
)
+
+ +

Definition at line 76 of file pearl-otf-import.ipf.

+ +
+
+ +

◆ otf_load_itx_all()

+ +
+
+ + + + + + + + +
variable otf_load_itx_all (string pathname)
+
+ +

Definition at line 31 of file pearl-otf-import.ipf.

+ +
+
+ +

◆ otf_load_itx_match()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable otf_load_itx_match (string pathname,
string matchstr 
)
+
+ +

Definition at line 53 of file pearl-otf-import.ipf.

+ +
+
+ +

◆ otf_rename_folders()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable otf_rename_folders (string pattern,
variable unique_index = defaultValue,
string new_suffix = defaultValue,
string match_str = defaultValue 
)
+
+ +

Definition at line 231 of file pearl-otf-import.ipf.

+ +
+
+ +

◆ otf_rename_folders_iterator()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable otf_rename_folders_iterator (dfref df,
string * sdata 
)
+
+ +

Definition at line 185 of file pearl-otf-import.ipf.

+ +
+
+ +

◆ otf_smo_int()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable otf_smo_int (wave win,
wave wout,
wave wpe,
variable smo 
)
+
+ +

Definition at line 304 of file pearl-otf-import.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=1 // Use modern global access method.
2 #pragma IgorVersion = 6.1
3 #pragma ModuleName = PearlOtfImport
4 #pragma version = 1.01
5 
6 // procedures for importing on-the-fly (OTF) scans
7 // OTF scans are saved as ITX files
8 // matthias muntwiler, 2013-02-22
9 // $Id$
10 
11 // introduction
12 // the latest version of the PEARL OTF server saves data in igor text (ITX)
13 // the files contain code which saves all data from one file into one data folder with a unique name
14 // multiple files can be selected in the explorer and loaded by a double click
15 
16 // description
17 // OTF data folder names have the format otf_date_time_suffix, where only suffix is user-defined
18 // thus, raw data folder names are unique
19 // data folder names can be converted to a shorter format
20 // an OTF data folder contains a wave for each measured quantity (detector)
21 // and the IN, ID, IV, and IU waves for additional beamline parameters
22 // detector waves must have a wave note containing the following key=value pairs:
23 // PV=name of EPICS process variable
24 // PhysicalType=physical type of the quantity in the same way as used by pearl-optics-import
25 // Axis1=wave name of principal X axis
26 
27 // convergence
28 // while the file formats may be different, data files generated by the OTF and EPICS scan tools
29 // shall ultimately produce the same data structures in an Igor experiment
30 
31 function otf_load_itx_all(pathname)
32  // loads all OTF files from a given path
33  // this function is for older files (before 2013-03-01) which do not specify a destination data folder
34  // newer files can be loaded by double click from the explorer
35  // without the danger of overwriting data from other files
36  string pathname
37  string filename
38 
39  if (strlen(pathname) <= 0)
40  newpath /o/q otf_load_itx
41  pathname = "otf_load_itx"
42  endif
43  string filelist = IndexedFile($pathname, -1, ".itx")
44  filelist = ListMatch(filelist, "otf*.itx", ";")
45  variable nfile = ItemsInList(filelist, ";")
46  variable ifile
47  for (ifile = 0; ifile < nfile; ifile += 1)
48  filename = StringFromList(ifile, filelist, ";")
49  otf_load_itx(pathname, filename)
50  endfor
51 end
52 
53 function otf_load_itx_match(pathname, matchstr)
54  // loads all OTF files from a given path whose names match a given string
55  // this function is for older files (before 2013-03-01) which do not specify a destination data folder
56  // newer files can be loaded by double click from the explorer
57  // without the danger of overwriting data from other files
58  string pathname
59  string matchstr
60  string filename
61 
62  if (strlen(pathname) <= 0)
63  newpath /o/q otf_load_itx
64  pathname = "otf_load_itx"
65  endif
66  string filelist = IndexedFile($pathname, -1, ".itx")
67  filelist = ListMatch(filelist, matchstr, ";")
68  variable nfile = ItemsInList(filelist, ";")
69  variable ifile
70  for (ifile = 0; ifile < nfile; ifile += 1)
71  filename = StringFromList(ifile, filelist, ";")
72  otf_load_itx(pathname, filename)
73  endfor
74 end
75 
76 function otf_load_itx(pathname, filename)
77  // loads a specific OTF file
78  // this function is for older files (before 2013-03-01) which do not specify a destination data folder
79  // newer files can be loaded by double click from the explorer
80  // without the danger of overwriting data from other files
81  string pathname
82  string filename
83 
84  dfref savedf = GetDataFolderDFR()
85  setdatafolder root:
86 
87  newdatafolder /s/o otf_load_itx_temp
88  if (strlen(pathname) > 0)
89  LoadWave /O/P=$pathname/Q/T filename
90  else
91  LoadWave /O/Q/T filename
92  endif
93  if (v_flag)
94  string foldername
95  foldername = ParseFilePath(3, s_filename, "/", 0, 0)
96  foldername = foldername[0,16]
97  foldername = CleanupName(foldername, 0)
98  //foldername = UniqueName(foldername, 11, 0)
99  renamedatafolder root:otf_load_itx_temp, $foldername
100  printf "loaded otf data from file %s into folder %s\r", s_filename, foldername
101  endif
102 
103  setdatafolder savedf
104 end
105 
106 function otf_gather_iterator(df, sdata)
107  // data folder iterator used by otf_gather_batch
108  dfref df
109  string &sdata // key=value list of parameters
110  // xwavematch
111  // ywavematch
112  // destfolder
113 
114  string src_name
115  string dst_name
116  string src_folder
117  string dst_folder
118  string df_id
119  string prefix, sdate, stime
120 
121  setdatafolder df
122  src_folder = GetDataFolder(0, df)
123  sscanf src_folder, "%[^_]_%[0-9]_%[0-9]", prefix, sdate, stime
124  df_id = ""
125  if (strlen(sdate) > 0)
126  df_id += "_" + sdate
127  endif
128  if (strlen(stime) > 0)
129  df_id += "_" + stime
130  endif
131  dst_folder = StringByKey("destfolder", sdata)
132 
133  src_name = StringByKey("xwavematch", sdata)
134  src_name = WaveList(src_name, "", "")
135  if (ItemsInList(src_name) >= 1)
136  src_name = StringFromList(0, src_name)
137  dst_name = dst_folder + src_name + df_id
138  //print src_name, dst_name
139  duplicate $src_name, $dst_name
140  endif
141 
142  src_name = StringByKey("ywavematch", sdata)
143  src_name = WaveList(src_name, "", "")
144  if (ItemsInList(src_name) >= 1)
145  src_name = StringFromList(0, src_name)
146  dst_name = dst_folder + src_name + df_id
147  //print src_name, dst_name
148  duplicate $src_name, $dst_name
149  endif
150 end
151 
152 function otf_gather_batch(ywavematch, xwavematch, destfolder)
153  // gathers (copies) OTF datasets in one data folder
154  // can be used for example for the Igor batch curve fitting tool
155  string ywavematch // match string identifies the y wave to be copied
156  string xwavematch // match string identifies the x wave to be copied
157  string destfolder // name of the destination data folder. folder does not have to exist.
158 
159  return gather_batch("otf*", ywavematch, xwavematch, destfolder)
160 end
161 
162 function gather_batch(foldermatch, ywavematch, xwavematch, destfolder)
163  // gathers (copies) OTF datasets in one data folder
164  // can be used for example for the Igor batch curve fitting tool
165  string foldermatch // match string to select data folders, e.g. "otf*"
166  string ywavematch // match string identifies the y wave to be copied
167  string xwavematch // match string identifies the x wave to be copied
168  string destfolder // name of the destination data folder. folder does not have to exist.
169 
170  dfref savedf = GetDataFolderDFR()
171  newdatafolder /o/s $destfolder
172  destfolder = GetDataFolder(1)
173 
174  string iteratordata = ""
175  iteratordata = ReplaceStringByKey("xwavematch", iteratordata, xwavematch)
176  iteratordata = ReplaceStringByKey("ywavematch", iteratordata, ywavematch)
177  iteratordata = ReplaceStringByKey("destfolder", iteratordata, destfolder)
178 
179  setdatafolder savedf
180  iteratordata = IterateDataFolders(foldermatch, otf_gather_iterator, iteratordata)
181 
182  setdatafolder savedf
183 end
184 
185 function otf_rename_folders_iterator(df, sdata)
186  // data folder iterator used by otf_rename_folders
187  dfref df
188  string &sdata // key=value list of parameters
189 
190  string pattern = StringByKey("pattern", sdata)
191  variable unique_index = NumberByKey("unique_index", sdata)
192  string new_suffix = StringByKey("new_suffix", sdata)
193 
194  string src_folder
195  string dst_folder
196  string sprefix, sdate, stime, ssuffix
197 
198  setdatafolder df
199  src_folder = GetDataFolder(0, df)
200  sprefix = "otf"
201  sscanf src_folder, "otf_%[0-9]_%[0-9]%s", sdate, stime, ssuffix
202  // return early if folder name does not match the expected pattern
203  if ((strlen(sdate) == 0) || (strlen(stime) == 0))
204  return 1
205  endif
206 
207  dst_folder = sprefix
208  if (cmpstr(pattern[0], "0") != 0)
209  dst_folder += "_" + sdate
210  endif
211  if (cmpstr(pattern[1], "0") != 0)
212  dst_folder += "_" + stime
213  endif
214  if (cmpstr(pattern[2], "0") != 0)
215  if (strlen(new_suffix) > 0)
216  ssuffix = "_" + new_suffix
217  endif
218  dst_folder += ssuffix
219  endif
220 
221  if ((unique_index > 0) || (CheckName(dst_folder, 11) != 0))
222  dst_folder = UniqueName(dst_folder + "_", 11, unique_index)
223  endif
224 
225  setdatafolder ::
226  print src_folder + " -> " + dst_folder
227  RenameDataFolder $src_folder, $dst_folder
228  return 0
229 end
230 
231 function otf_rename_folders(pattern, [unique_index, new_suffix, match_str])
232  // renames OTF data folders by omitting parts of the file name
233  string pattern // string of zeros and ones indicates which name parts to keep
234  // pos 1: date
235  // pos 2: time
236  // pos 3: custom suffix
237  variable unique_index // if you remove date and time,
238  // this start index will be used to make names unique
239  // if non-zero, new names will be forced to include a unique index
240  // if zero (default), new names will get a unique index only in case of a conflict
241  // optional, defaults to 0
242  string new_suffix
243  // replace old suffix by this one
244  // if empty (default), the old suffix will be kept
245  // optional, defaults to empty string
246  string match_str // match folder name to rename
247  // optional, defaults to "otf*" (matches all OTF folders)
248 
249  dfref savedf = GetDataFolderDFR()
250 
251  if (ParamIsDefault(unique_index))
252  unique_index = 0
253  endif
254  if (ParamIsDefault(new_suffix))
255  new_suffix = ""
256  endif
257  if (ParamIsDefault(match_str))
258  match_str = "otf*"
259  endif
260 
261  string iteratordata = ""
262  iteratordata = ReplaceStringByKey("pattern", iteratordata, pattern)
263  iteratordata = ReplaceNumberByKey("unique_index", iteratordata, unique_index)
264  iteratordata = ReplaceStringByKey("new_suffix", iteratordata, new_suffix)
265 
266  iteratordata = IterateDataFolders(match_str, otf_rename_folders_iterator, iteratordata)
267 
268  setdatafolder savedf
269 end
270 
271 function otf_interp(e1, e2, npts, smo)
272  variable e1
273  variable e2
274  variable npts
275  variable smo
276 
277  wave ch1 = current_ch1
278  wave ch2 = current_ch2
279  wave pe = photonenergy
280  wave cff
281  wave rc = ringcurrent
282 
283  duplicate /o ch1, current_ch1_int
284  wave ch1i = current_ch1_int
285  duplicate /o ch2, current_ch2_int
286  wave ch2i = current_ch2_int
287  duplicate /o pe, photonenergy_int
288  wave pei = photonenergy_int
289  duplicate /o cff, cff_int
290  wave cffi = cff_int
291  duplicate /o rc, ringcurrent_int
292  wave rci = ringcurrent_int
293 
294  redimension /n=(npts) ch1i, ch2i, pei, cffi, rci
295  setscale /i x e1, e2, "eV", ch1i, ch2i, pei, cffi, rci
296 
297  otf_smo_int(ch1, ch1i, pe, smo)
298  otf_smo_int(ch2, ch2i, pe, smo)
299  otf_smo_int(pe, pei, pe, smo)
300  otf_smo_int(cff, cffi, pe, smo)
301  otf_smo_int(rc, rci, pe, smo)
302 end
303 
304 function otf_smo_int(win, wout, wpe, smo)
305  wave win
306  wave wout
307  wave wpe
308  variable smo
309 
310  //duplicate /o win, wtmp
311  duplicate /free win, wtmp
312  smooth /b /e=3 smo, wtmp
313  wout = interp(x, wpe, wtmp)
314 end
variable otf_gather_iterator(dfref df, string *sdata)
+
string IterateDataFolders(string matchStr, funcref iterator, string sdata, string progress_title=defaultValue)
Definition: pearl-tools.ipf:79
+
variable otf_load_itx(string pathname, string filename)
+
variable otf_interp(variable e1, variable e2, variable npts, variable smo)
+
variable gather_batch(string foldermatch, string ywavematch, string xwavematch, string destfolder)
+
variable otf_load_itx_match(string pathname, string matchstr)
+
variable otf_gather_batch(string ywavematch, string xwavematch, string destfolder)
+
variable otf_rename_folders(string pattern, variable unique_index=defaultValue, string new_suffix=defaultValue, string match_str=defaultValue)
+
variable otf_rename_folders_iterator(dfref df, string *sdata)
+
variable otf_load_itx_all(string pathname)
+
variable otf_smo_int(wave win, wave wout, wave wpe, variable smo)
+
+
+Namespaces | +Functions
-
pearl-pmsco-import.ipf File Reference
+
pearl-pmsco-import.ipf File Reference
+

data import/export procedures for multiple scattering calculations. +More...

+

Go to the source code of this file.

+ + + + + +

+Namespaces

 PearlPmscoImport
 data import/export procedures for multiple scattering calculations.
 
+ + + + + + + + + + +

+Functions

string pmsco_save_scan (string pathname, string filename, string energy, string theta, string phi, string alpha, string intensity, string sigma, dfref sdfr=defaultValue)
 save waves in a PMSCO scan data file. More...
 
static string save_scan_helper (string destname, string value, wave template, dfref destdfr, string wavenames)
 helper function for save_pmsco_scan() More...
 
string pmsco_load_xyz (string pathname, string filename)
 load an xyz cluster file More...
 
+

Detailed Description

+

data import/export procedures for multiple scattering calculations.

+
Author
matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
+ + +

Definition in file pearl-pmsco-import.ipf.

+

Function Documentation

+ +

◆ pmsco_load_xyz()

+ +
+
+ + + + + + + + + + + + + + + + + + +
string pmsco_load_xyz (string pathname,
string filename 
)
+
+ +

load an xyz cluster file

+

load an xyz cluster file into the current data folder the wave names are at (atom types), xx, yy, and zz. at is a text wave containing chemical symbols. existing waves are overwritten.

+
Parameters
+ + + +
pathnamename of igor symbolic path. can be empty (path is taken from filename argument).
filenamefile system path. can be empty (will open dialog).
+
+
+ +

Definition at line 188 of file pearl-pmsco-import.ipf.

+ +
+
+ +

◆ pmsco_save_scan()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string pmsco_save_scan (string pathname,
string filename,
string energy,
string theta,
string phi,
string alpha,
string intensity,
string sigma,
dfref sdfr = defaultValue 
)
+
+ +

save waves in a PMSCO scan data file.

+
Warning
experimental. this function is work in progress.
+

cases

    +
  • phd scan: separate energy, theta, phi, alpha, intensity waves
  • +
  • hemi scan: separate energy, theta, phi, intensity waves
  • +
  • polar/azi scan: intensity wave, angle is in x scale
  • +
+

options

    +
  • sigma wave
  • +
+

the data arguments are strings and can be

    +
  • the name of an existing wave (optionally including a path relative to the specified source folder),
  • +
  • the string representation of a constant numeric value,
  • +
  • a dimension specifier ("x", "y", "z" or "t") referring to the dimension scale of the intensity wave, or
  • +
  • an empty string if the corresponding axis should not be saved.
  • +
+

wave names can include a path relative to the specified source data folder. by default, the function looks in the folder specified by the sdfr argument.

+
Parameters
+ + + +
pathnamename of igor symbolic path to destination folder. prompt user if empty.
filenamerequested file name. prompt user if empty.
+
+
+
Note
the extension should include the symbols of the included parameters in the order "etpais". if the intensity wave contains a modulation function, ".modf" should be inserted before the extension. in interactive mode, igor tends to override the file extension with a standard one like ".txt".
+
Parameters
+ + + + + + + + +
energyenergy specification. see description above.
thetatheta specification. see description above.
phiphi specification. see description above.
alphaalpha specification. see description above.
intensityname of intensity (or modulation) wave. this parameter is mandatory and must refer to an existing wave.
sigmasigma specification. see description above.
sdfrsource data folder reference. default: current data folder.
+
+
+
Returns
file name
+ +

Definition at line 88 of file pearl-pmsco-import.ipf.

+ +
+
+ +

◆ save_scan_helper()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static string save_scan_helper (string destname,
string value,
wave template,
dfref destdfr,
string wavenames 
)
+
+static
+
+ +

helper function for save_pmsco_scan()

+ +

Definition at line 126 of file pearl-pmsco-import.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #pragma IgorVersion = 6.2
3 #pragma ModuleName = PearlPmscoImport
4 
5 // copyright (c) 2018 Paul Scherrer Institut
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 // http:///www.apache.org/licenses/LICENSE-2.0
11 //
12 // Please acknowledge the use of this code.
13 
28 
33 
34 
88 function /s pmsco_save_scan(pathname, filename, energy, theta, phi, alpha, intensity, sigma, [sdfr])
89  string pathname
90  string filename
91  string energy
92  string theta
93  string phi
94  string alpha
95  string intensity
96  string sigma
97  dfref sdfr
98 
99  //string fileext
100  //fileext = StringFromList(ItemsInList(filename, ".") - 1, filename, ".")
101 
102  dfref savedf = GetDataFolderDFR()
103  dfref tempdf = NewFreeDataFolder()
104 
105  if (ParamIsDefault(sdfr))
106  dfref sdfr = savedf
107  endif
108  SetDataFolder sdfr
109  wave w_intensity = $intensity
110  string wavenames = ""
111 
112  wavenames = save_scan_helper("w_energy", energy, w_intensity, tempdf, wavenames)
113  wavenames = save_scan_helper("w_theta", theta, w_intensity, tempdf, wavenames)
114  wavenames = save_scan_helper("w_phi", phi, w_intensity, tempdf, wavenames)
115  wavenames = save_scan_helper("w_alpha", alpha, w_intensity, tempdf, wavenames)
116  wavenames = save_scan_helper("w_intensity", intensity, w_intensity, tempdf, wavenames)
117  wavenames = save_scan_helper("w_sigma", sigma, w_intensity, tempdf, wavenames)
118 
119  setdatafolder tempdf
120  save /b /g /m="\n" /p=$pathname wavenames as filename
121  setdatafolder savedf
122 end
123 
126 static function /s save_scan_helper(destname, value, template, destdfr, wavenames)
127  string destname
128  string value
129  wave template
130  dfref destdfr
131  string wavenames
132 
133  variable err = 0
134  if (strlen(value) > 0)
135  if (exists(value) == 1)
136  duplicate $value, destdfr:$destname
137  wave /sdfr=destdfr w=$destname
138  else
139  duplicate template, destdfr:$destname
140  wave /sdfr=destdfr w=$destname
141  variable numval = str2num(value)
142  string msg
143  if (numtype(numval) == 0)
144  w = numval
145  //elseif (cmpstr(value[0,0], "%") == 0)
146  else
147  strswitch(value)
148  case "x":
149  w = DimOffset(template, 0) + DimDelta(template, 0) * p
150  break
151  case "y":
152  w = DimOffset(template, 1) + DimDelta(template, 1) * q
153  break
154  case "z":
155  w = DimOffset(template, 2) + DimDelta(template, 2) * r
156  break
157  case "t":
158  w = DimOffset(template, 3) + DimDelta(template, 3) * s
159  break
160  default:
161  err = 1
162  sprintf msg, "invalid %s argument", StringFromList(1, destname, "_")
163  endswitch
164  endif
165  endif
166  if (err == 0)
167  wavenames = AddListItem(destname, wavenames, ";", inf)
168  variable npts = DimSize(w, 0) * max(DimSize(w, 1), 1) * max(DimSize(w, 2), 1) * max(DimSize(w, 3), 1)
169  Redimension /n=(npts) w
170  else
171  abort msg
172  endif
173  endif
174  return wavenames
175 end
176 
188 function /s pmsco_load_xyz(pathname, filename)
189  string pathname
190  string filename
191 
192  string cis = "N=at;N=xx;N=yy;N=zz;"
193  LoadWave /A /B=cis /J /K=0 /L={0, 2, 0, 0, 0} /V={" ", " ", 0, 0} /O /P=$pathname filename
194  wave /t at
195  at = unpadstring(at, 32)
196 end
string pmsco_save_scan(string pathname, string filename, string energy, string theta, string phi, string alpha, string intensity, string sigma, dfref sdfr=defaultValue)
save waves in a PMSCO scan data file.
+
static string save_scan_helper(string destname, string value, wave template, dfref destdfr, string wavenames)
helper function for save_pmsco_scan()
+
string pmsco_load_xyz(string pathname, string filename)
load an xyz cluster file
+
+
+Functions
pearl-polar-coordinates.ipf File Reference

Go to the source code of this file.

+ + + + + + + + + + + + +

+Functions

variable cart2polar (variable xx, variable yy, variable zz, variable *radius, variable *theta, variable *phi)
 
variable cart2polar_wave (wave in, wave out)
 
variable polar2cart (variable radius, variable theta, variable phi, variable *xx, variable *yy, variable *zz)
 
variable polar2cart_wave (wave in, wave out)
 
variable polar_distance (variable polar1, variable azim1, variable polar2, variable azim2)
 
+

Function Documentation

+ +

◆ cart2polar()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable cart2polar (variable xx,
variable yy,
variable zz,
variable * radius,
variable * theta,
variable * phi 
)
+
+ +

Definition at line 10 of file pearl-polar-coordinates.ipf.

+ +
+
+ +

◆ cart2polar_wave()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable cart2polar_wave (wave in,
wave out 
)
+
+ +

Definition at line 36 of file pearl-polar-coordinates.ipf.

+ +
+
+ +

◆ polar2cart()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable polar2cart (variable radius,
variable theta,
variable phi,
variable * xx,
variable * yy,
variable * zz 
)
+
+ +

Definition at line 48 of file pearl-polar-coordinates.ipf.

+ +
+
+ +

◆ polar2cart_wave()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable polar2cart_wave (wave in,
wave out 
)
+
+ +

Definition at line 58 of file pearl-polar-coordinates.ipf.

+ +
+
+ +

◆ polar_distance()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable polar_distance (variable polar1,
variable azim1,
variable polar2,
variable azim2 
)
+
+ +

Definition at line 69 of file pearl-polar-coordinates.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=3
2 #pragma version = 1.1
3 #pragma IgorVersion = 6.1
4 #pragma ModuleName = PearlPolarCoordinates
5 
6 // author: matthias.muntwiler@psi.ch
7 // Copyright (c) 2011-13 Paul Scherrer Institut
8 // $Id$
9 
10 function cart2polar(xx, yy, zz, radius, theta, phi)
11  // converts a 3-vector from Cartesian to polar coordinates
12  variable xx, yy, zz
13  variable &radius, &theta, &phi // angles in degrees
14 
15  radius = sqrt(xx^2 + yy^2 + zz^2)
16 
17  if (radius > 0)
18  theta = acos(zz / radius) * 180 / pi
19  else
20  theta = 0
21  endif
22 
23  if (xx > 0)
24  phi = atan(yy / xx) * 180 / pi
25  elseif (xx < 0)
26  phi = atan(yy / xx) * 180 / pi + 180
27  else
28  if (yy > 0)
29  phi = 90
30  else
31  phi = 270
32  endif
33  endif
34 end
35 
36 function cart2polar_wave(in, out)
37  // converts a wave of 3-vectors from Cartesian to polar coordinates
38  wave in // wave with dimensions (3, N), N >= 1, (x, y, z)
39  wave out // wave same dimensions as in, (radius, theta, phi)
40  // angles in degrees
41 
42  out[0][] = sqrt(in[0][q]^2 + in[1][q]^2 + in[2][q]^2)
43  out[1][] = acos(in[2][q] / out[0][q]) * 180 / pi
44  out[2][] = atan(in[1][q] / in[0][q]) * 180 / pi + 180 * (in[0][q] < 0)
45  out[2][] = numtype(out[2][q]) == 0 ? out[2][q] : 90 + 180 * (in[1][q] < 0)
46 end
47 
48 function polar2cart(radius, theta, phi, xx, yy, zz)
49  // converts a 3-vector from Cartesian to polar coordinates
50  variable radius, theta, phi // angles in degrees
51  variable &xx, &yy, &zz
52 
53  xx = radius * sin(theta * pi / 180) * cos(phi * pi / 180)
54  yy = radius * sin(theta * pi / 180) * sin(phi * pi / 180)
55  zz = radius * cos(theta * pi / 180)
56 end
57 
58 function polar2cart_wave(in, out)
59  // converts a wave of 3-vectors from polar to Cartesian coordinates
60  wave in // wave with dimensions (3, N), N >= 1, (radius, theta, phi)
61  // angles in degrees
62  wave out // wave same dimensions as in, (x, y, z)
63 
64  out[0][] = in[0][q] * sin(in[1][q] * pi / 180) * cos(in[2][q] * pi / 180)
65  out[1][] = in[0][q] * sin(in[1][q] * pi / 180) * sin(in[2][q] * pi / 180)
66  out[2][] = in[0][q] * cos(in[1][q] * pi / 180)
67 end
68 
69 function polar_distance(polar1, azim1, polar2, azim2)
70  // returns the angle between two spherical coordinates
71  variable polar1, azim1
72  // angles in degrees
73  variable polar2, azim2
74  // angles in degrees
75 
76  variable xx1, yy1, zz1
77  variable xx2, yy2, zz2
78 
79  polar2cart(1, polar1, azim1, xx1, yy1, zz1)
80  polar2cart(1, polar2, azim2, xx2, yy2, zz2)
81 
82  variable vv
83  vv = (xx1 * xx2 + yy1 * yy2 + zz1 * zz2) / sqrt(xx1^2 + yy1^2 + zz1^2) / sqrt(xx2^2 + yy2^2 + zz2^2)
84  return acos(vv) * 180 / pi
85 end
variable polar2cart_wave(wave in, wave out)
+
variable cart2polar(variable xx, variable yy, variable zz, variable *radius, variable *theta, variable *phi)
+
variable cart2polar_wave(wave in, wave out)
+
variable polar_distance(variable polar1, variable azim1, variable polar2, variable azim2)
+
variable polar2cart(variable radius, variable theta, variable phi, variable *xx, variable *yy, variable *zz)
+
+
+Namespaces | +Functions | +Variables
-
pearl-pshell-import.ipf File Reference
+
pearl-pshell-import.ipf File Reference
+

import data from PShell +More...

+
#include <HDF5 Browser>
+#include "pearl-gui-tools"
+#include "pearl-area-import"
+

Go to the source code of this file.

+ + + + + +

+Namespaces

 PearlPShellImport
 import data from PShell
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

variable psh5_open_file (string ANickName, string APathName, string AFileName)
 open a HDF5 file created by the PShell data acquisition program and prepare the data folder. More...
 
variable psh5_close_file (variable fileID)
 close a HDF5 file opened by psh5_open_file. More...
 
string psh5_load_complete (string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
 load everything from a PShell data file. More...
 
string psh5_load_preview (string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue, string pref_scans=defaultValue, string pref_datasets=defaultValue)
 load a preview image from a PShell data file. More...
 
string psh5_load_scan_complete (variable fileID, string scanpath, variable load_data=defaultValue, variable load_attr=defaultValue)
 load all data of a selected scan from a PShell data file. More...
 
string psh5_list_scans (variable fileID)
 list scan groups of a PShell data file. More...
 
string psh5_list_scan_datasets (variable fileID, string scanpath, variable include_regions=defaultValue)
 list datasets of a PShell scan group. More...
 
string psh5_list_scan_regions (variable fileID, string scanpath)
 list regions of a PShell scan group. More...
 
string psh5_load_scan_data (variable fileID, string scanpath)
 load all datasets of a PShell scan group. More...
 
string psh5_load_scan_attrs (variable fileID, string scanpath, variable attr_sets=defaultValue)
 load attributes of a PShell scan group. More...
 
string psh5_load_scan_meta (variable fileID, string scanpath)
 load metadata of a PShell scan group. More...
 
string psh5_load_dataset (variable fileID, string scanpath, string datasetname, variable set_scale=defaultValue)
 load a dataset from an open PShell HDF5 file. More...
 
static string select_dataset (string file_datasets, string pref_datasets)
 select the preferred dataset from a list of available datasets. More...
 
string psh5_load_scan_preview (variable fileID, string scanpath, variable set_scale=defaultValue, string pref_datasets=defaultValue)
 load a preview dataset from an open PShell HDF5 file. More...
 
string psh5_load_scan_section (variable fileID, string scanpath, variable dim, variable set_scale=defaultValue, string pref_datasets=defaultValue)
 load a longitudinal section of a scan from an open PShell HDF5 file. More...
 
variable psh5_load_dataset_meta (variable fileID, string datapath, string datasetname, wave datawave)
 load metadata of a PShell dataset. More...
 
string psh5_load_dataset_slabs (variable fileID, string datapath, string datasetname, variable progress=defaultValue)
 load a dataset slab-wise from the open PShell HDF5 file. More...
 
string psh5_load_dataset_slab (variable fileID, string datapath, string datasetname, variable dim2start, variable dim2count, variable dim3start, variable dim3count)
 load a single image from the open PShell data file. More...
 
variable ps_set_dimlabels (wave data)
 set dimension labels according to the axis type More...
 
variable ps_set_dimlabels2 (wave data, string name)
 set dimension labels according to the axis type More...
 
static dfr find_scan_folder (dfref dataDF)
 find the scan folder More...
 
static dfr find_attr_folder (dfref dataDF)
 find the attributes data folder More...
 
variable ps_scale_datasets ()
 set the dimension scales of loaded PShell Scienta datasets according to attributes. More...
 
variable ps_scale_dataset (wave data)
 set the dimension scales of a loaded PShell Scienta dataset according to attributes. More...
 
static wave find_scale_wave (string name, dfref dataDF, dfref scanDF, dfref attrDF)
 
variable ps_detect_scale (wave ax, wave lo, wave hi, wave un)
 detect the dimension scales from attributes. More...
 
variable ps_scale_dataset_2 (wave data, wave ax, wave lo, wave hi, wave un)
 set the dimension scales of a dataset. More...
 
string psh5_load_reduced (string ANickName, string APathName, string AFileName, funcref reduction_func, string reduction_param, variable progress=defaultValue, variable nthreads=defaultValue)
 load and reduce the ScientaImage dataset of the first scan of a PShell data file. More...
 
string psh5_load_dataset_reduced (variable fileID, string scanpath, string datasetname, funcref reduction_func, string reduction_param, variable progress=defaultValue, variable nthreads=defaultValue)
 load a reduced dataset from the open PShell HDF5 file. More...
 
static threadsafe variable reduce_slab_worker (funcref reduction_func)
 
static threadsafe wave reduce_slab_image (wave slabdata, wave image, funcref reduction_func, string reduction_param)
 
string psh5_load_info (string APathName, string AFileName)
 load descriptive info from a PShell data file. More...
 
string psh5_load_scan_info (variable fileID, string scanpath)
 load descriptive info from a PShell scan. More...
 
static string twave2list (wave wt, string sep)
 convert text wave to list. More...
 
static string wave2list (wave w, string format, string sep)
 convert numeric wave to list. More...
 
+ + + + + + + + + + + + + + + + + + + + + + + + + +

+Variables

const string kEnergyDimLabel = "energy"
 Dimension label for the energy dispersive dimension of multi-dimensional datasets. More...
 
const string kAngleDimLabel = "angle"
 Dimension label for the angle dispersive dimension of multi-dimensional datasets. More...
 
const string kScanDimLabel = "scan"
 Dimension label for the scan dimension of multi-dimensional datasets. More...
 
const string kDataDimLabel = "data"
 Dimension label for the data dimension. More...
 
const string kPreviewDatasets = "ScientaImage;ScientaSpectrum;ImageAngleDistribution;ImageEnergyDistribution;Counts;SampleCurrent;"
 List of preferred datasets to load for preview. More...
 
const string kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;"
 List of datasets that must be loaded to determine the axis scaling of a Scienta image. More...
 
const string kTransposedDatasets = "ScientaImage;"
 List of datasets that should be transposed upon loading. More...
 
const variable kDetectorSensitivity = 4
 multiply scienta detector intensity by this value to get actual counts. More...
 
+

Detailed Description

+

import data from PShell

+

HDF5 file import from the PShell data acquisition program. the main import functions are:

+ +

the following helper functions are also needed:

+ +
Author
matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
+ + +

Definition in file pearl-pshell-import.ipf.

+

Function Documentation

+ +

◆ find_attr_folder()

+ +
+
+ + + + + +
+ + + + + + + + +
static dfr find_attr_folder (dfref dataDF)
+
+static
+
+ +

find the attributes data folder

+

this is the :attr folder.

+ +

Definition at line 1458 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ find_scale_wave()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static wave find_scale_wave (string name,
dfref dataDF,
dfref scanDF,
dfref attrDF 
)
+
+static
+
+ +

Definition at line 1546 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ find_scan_folder()

+ +
+
+ + + + + +
+ + + + + + + + +
static dfr find_scan_folder (dfref dataDF)
+
+static
+
+ +

find the scan folder

+

the scan folder is the one that contains the :attr folder the data and scan folders may refer to the same folder.

+ +

Definition at line 1441 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ ps_detect_scale()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable ps_detect_scale (wave ax,
wave lo,
wave hi,
wave un 
)
+
+ +

detect the dimension scales from attributes.

+

the function checks the data , scan and attributes folders for scan parameters. the results are written to the provided waves. the function is normally called by ps_scale_datasets() but can also be used independently.

+

the current datafolder must be the data or the scan folder. the data folder contains the waves that are to be scaled. the scan folder contains the scan positions and the :attr folder.

+

the provided waves are redimensioned by the function, and dimension labels are set. the scale parameters can then be extracted by keyword, e.g.,

    +
  • lo[%energy] analyser energy dimension.
  • +
  • lo[%angle] analyser angle dimension.
  • +
  • lo[%scan] scan dimension.
  • +
  • lo[%data] data dimension.
  • +
+

the function tries to read the following waves, in the data, scan, and attributes folders, where the first folder in the list takes precedence. it may fall back to more or less reasonable default values if no data is not found.

    +
  • LensMode
  • +
  • ScientaChannelBegin
  • +
  • ScientaChannelEnd
  • +
  • ScientaSliceBegin
  • +
  • ScientaSliceEnd
  • +
  • ScanWritables
  • +
  • wave referenced by ScanWritables[0]
  • +
+
Parameters
+ + + + + +
axtext wave to receive the axis labels.
lowave to receive the lower limits.
hiwave to receive the upper limits.
untext wave to receive the unit labels.
+
+
+
Returns
the function results are written to the lo, hi, un, and ax waves.
+
Version
this function supports regions from version 1.03. check that you're in the correct data folder!
+ +

Definition at line 1603 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ ps_scale_dataset()

+ +
+
+ + + + + + + + +
variable ps_scale_dataset (wave data)
+
+ +

set the dimension scales of a loaded PShell Scienta dataset according to attributes.

+

the current datafolder must contain the :attr folder. the data wave can be in the current folder or a sub-folder.

+

the dimension labels of the dataset waves must have been set correctly, e.g. by ps_set_dimlabels(). this is implicitly done by the high-level load functions.

+

the function is useful if a single dataset is loaded and scaled. if multiple datasets are loaded, ps_scale_datasets() is slightly more efficient.

+
Parameters
+ + +
datadata wave to be scaled. dimension labels (index -1) must be set correctly, cf. ps_set_dimlabels().
+
+
+
Version
this function supports regions from version 1.03.
+ +

Definition at line 1532 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ ps_scale_dataset_2()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable ps_scale_dataset_2 (wave data,
wave ax,
wave lo,
wave hi,
wave un 
)
+
+ +

set the dimension scales of a dataset.

+

the function is normally called by ps_scale_datasets() but can also be used independently. the limits and units must be given as function arguments with proper dimension labels.

+

the provided limit and unit waves must have dimension labels matching the -1 index dimension labels of the data wave, such as set by the ps_detect_scale() function. the scale parameters are extracted by keyword, e.g.,

    +
  • lo[%energy] analyser energy dimension.
  • +
  • lo[%angle] analyser angle dimension.
  • +
  • lo[%scan] scan dimension.
  • +
  • lo[%data] data dimension.
  • +
+

if the data dimension labels and units are at their defaults ("value" and "arb.", respectively), the function tries to read them from the existing wave note ("AxisLabelD" and "AxisUnitD"), or based on the wave name if the name is one of the known measurement variables: "ScientaImage", "ImageAngleDistribution", "ScientaAngleDistribution", "ScientaSpectrum", "ImageEnergyDistribution", "ScientaEnergyDistribution", "SampleCurrent", "RefCurrent", "AuxCurrent", "MachineCurrent".

+
Parameters
+ + + + + + +
datadata wave to be scaled. dimension labels (index -1) must be set to match the limit waves.
axaxis labels. the axis labels are written to the wave note in the format AxisLabel%s=%s where X, Y, Z, D is substituted for the first place holder and the label for the second one.
lolower limits. the lower limits are applied using the SetScale operation.
hiupper limits. the upper limits are applied using the SetScale operation.
ununit labels. the unit labels are applied using the SetScale operation.
+
+
+
Version
this function supports regions from version 1.03.
+ +

Definition at line 1763 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ ps_scale_datasets()

+ +
+
+ + + + + + + +
variable ps_scale_datasets ()
+
+ +

set the dimension scales of loaded PShell Scienta datasets according to attributes.

+

datasets listed in the ScanReadables waves are scaled according to the attribute waves in the data, scan, and attributes folders, whichever is found first.

+

the current datafolder must contain the ScanReadables wave and the :attr folder. the ScanReadables text wave contains names of the waves to scale. wave names can include a relative path to a sub-folder. the path separator is "/".

+

the dimension labels of the dataset waves must have been set correctly, e.g. by ps_set_dimlabels(). this is implicitly done by the high-level load functions.

+
Version
this function supports regions from version 1.03. check that you're in the correct data folder!
+ +

Definition at line 1486 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ ps_set_dimlabels()

+ +
+
+ + + + + + + + +
variable ps_set_dimlabels (wave data)
+
+ +

set dimension labels according to the axis type

+

this function asserts a particular ordering of dimensions types based on the name of the wave for ScientaImage, ScientaSpectrum, ImageAngleDistribution, ImageEnergyDistribution. all other waves must be one-dimensional, and the dimension must be the scan dimension.

+

dimension labels are required by scaling functions.

+
Parameters
+ + +
datadata wave as loaded from PShell file
+
+
+
Returns
    +
  • 0 all labels set successfully.
  • +
  • 1 unidentified data source.
  • +
  • 2 wave does not contain data.
  • +
+
+ +

Definition at line 1365 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ ps_set_dimlabels2()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable ps_set_dimlabels2 (wave data,
string name 
)
+
+ +

set dimension labels according to the axis type

+

same as ps_set_dimlabels() except that the dimension labels are set according to a separate name argument instead of the wave name.

+
Parameters
+ + + +
datadata wave as loaded from PShell file.
nameoriginal name of the dataset in the PShell file.
+
+
+
Returns
    +
  • 0 all labels set successfully.
  • +
  • 1 unidentified data source.
  • +
  • 2 wave does not contain data.
  • +
+
+ +

Definition at line 1384 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_close_file()

+ +
+
+ + + + + + + + +
variable psh5_close_file (variable fileID)
+
+ +

close a HDF5 file opened by psh5_open_file.

+

this function just closes the HDF5 file. no change is made to the loaded data.

+
Parameters
+ + +
fileIDID of open HDF5 file from psh5_open_file().
+
+
+ +

Definition at line 139 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_list_scan_datasets()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_list_scan_datasets (variable fileID,
string scanpath,
variable include_regions = defaultValue 
)
+
+ +

list datasets of a PShell scan group.

+

the function returns a list of all datasets of the selected scan. this does not include datasets from the attributes sub-group.

+
Note
in a future version, an option may be introduced to filter datasets by function (Readable and/or Writable).
+
Parameters
+ + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
+
+
+
Returns
semicolon-separated list of dataset paths.
+
Version
since version 1.03 this function returns paths relative to scanpath.
+ +

Definition at line 439 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_list_scan_regions()

+ +
+
+ + + + + + + + + + + + + + + + + + +
string psh5_list_scan_regions (variable fileID,
string scanpath 
)
+
+ +

list regions of a PShell scan group.

+

the function returns a list of all region groups of the selected scan.

+
Parameters
+ + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
+
+
+
Returns
semicolon-separated list of datagroup paths.
+ +

Definition at line 480 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_list_scans()

+ +
+
+ + + + + + + + +
string psh5_list_scans (variable fileID)
+
+ +

list scan groups of a PShell data file.

+

the function returns a list of all top-level groups whose name starts with "scan".

+
Parameters
+ + +
fileIDID of open HDF5 file from psh5_open_file().
+
+
+
Returns
semicolon-separated list of group paths.
+ +

Definition at line 404 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_complete()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_complete (string ANickName,
string APathName,
string AFileName,
variable load_data = defaultValue,
variable load_attr = defaultValue 
)
+
+ +

load everything from a PShell data file.

+
Parameters
+ + + + + + +
ANickNamedestination folder name (top level under root)
APathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
AFileNameif empty a dialog box shows up
load_dataselect whether datasets (positioners and detectors) are loaded.
    +
  • 1 (default) load data.
  • +
  • 0 do not load data.
  • +
+
load_attrselect whether attributes (auxiliary device readbacks) are loaded. for proper wave scaling, the attributes must be loaded.
    +
  • 1 (default) load attributes.
  • +
  • 0 do not load attributes.
  • +
+
+
+
+
Returns
complete path of the loaded file if successful. empty string otherwise.
+
+global string s_filepath in new data folder contains the full file path on disk.
+
+global string s_scanpaths in new data folder contains a list of scan groups inside the file.
+ +

Definition at line 169 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_dataset()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_dataset (variable fileID,
string scanpath,
string datasetname,
variable set_scale = defaultValue 
)
+
+ +

load a dataset from an open PShell HDF5 file.

+

if the dataset has a maximum of two dimensions, the function loads it at once. if it has more than two dimension, the function calls psh5_load_dataset_slabs() to load the data slab by slab.

+ +

the dataset is loaded into the current data folder unless datasetname contains a region specifier. in the latter case, the dataset is loaded into sub-folder with the name of the region. the function returns from the original data folder.

+
Parameters
+ + + + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
datasetnamename of the dataset. the name of the loaded wave is a cleaned up version of the dataset name. the name can include the region name as a relative path, e.g. "region1/ScientaSpectrum". in this case, the dataset is loaded into a sub-folder named "region1".
set_scaleby default, the function tries to set the wave scaling if the attributes have been loaded. if multiple datasets are loaded from a file, it is more efficient to set the scaling of all loaded datasets at the end by calling ps_scale_datasets().
    +
  • 1 (default) set the wave scaling.
  • +
  • 0 do not set the wave scaling.
  • +
+
+
+
+
Returns
name of loaded wave if successful. empty string otherwise.
+
Version
this function supports regions as of version 1.03.
+ +

Definition at line 688 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_dataset_meta()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
variable psh5_load_dataset_meta (variable fileID,
string datapath,
string datasetname,
wave datawave 
)
+
+ +

load metadata of a PShell dataset.

+

"metadata" are the HDF5 attributes attached to the scan dataset.

+

data is added to the wave note.

+
Parameters
+ + + + + +
fileIDID of open HDF5 file from psh5_open_file().
datapathpath to the containing group in the HDF5 file. path separator is the slash "/".
datasetnamename of the dataset. may include relative path.
datawavemetadata is added to the wave note of this wave.
+
+
+
Returns
0 if successful, non-zero if an error occurred.
+ +

Definition at line 1073 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_dataset_reduced()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_dataset_reduced (variable fileID,
string scanpath,
string datasetname,
funcref reduction_func,
string reduction_param,
variable progress = defaultValue,
variable nthreads = defaultValue 
)
+
+ +

load a reduced dataset from the open PShell HDF5 file.

+

the function loads the dataset image by image using the hyperslab option and applies a custom reduction function to each image. the results from the reduction function are written to the ReducedData1, ReducedData2, etc. waves. the raw data are discarded.

+

by default, the reduction function is called in separate threads to reduce the total loading time. (see the global variable psh5_perf_secs which reports the total run time of the function.) the effect varies depending on the balance between file loading (image size) and data processing (complexity of the reduction function). for debugging the reduction function, multi-threading can be disabled.

+

if the reduction function requires the image waves to be scaled properly, the attributes must have been loaded by psh5_load_scan_attrs() before. in this case, the scales of the result waves are also set by the function. otherwise, the results can also be scaled by ps_scale_dataset() later.

+
Parameters
+ + + + + + + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to scan group in the HDF5 file.
datasetnamename of the dataset. this must currently be "ScientaImage", other data is not supported. the name of the loaded wave is a cleaned up version of the dataset name. the name can include the region name as a relative path, e.g. "region1/ScientaImage". in this case, the dataset is loaded into a sub-folder named "region1".
reduction_funccustom data reduction function. this can be any user-defined function which has the same parameters as adh5_default_reduction. some reduction functions are predefined in the PearlScientaPreprocess module.
reduction_paramparameter string for the reduction function.
progressprogress window.
    +
  • 1 (default) show progress window
  • +
  • 0 do not show progress window
  • +
+
nthreads
    +
  • -1 (default) use as many threads as there are processor cores (in addition to main thread).
  • +
  • 0 use main thread only (for debugging and profiling).
  • +
  • >= 1 use a fixed number of (additional) threads.
  • +
+
+
+
+
Returns
semicolon-separated list of the loaded dataset ReducedData1, ReducedData2, etc. if successful. auxiliary waves, scan positions, attributes are loaded but not listed in the string. empty string if an error occurred. error messages are printed to the history.
+
Version
this function supports regions as of version 1.03.
+ +

Definition at line 2022 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_dataset_slab()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_dataset_slab (variable fileID,
string datapath,
string datasetname,
variable dim2start,
variable dim2count,
variable dim3start,
variable dim3count 
)
+
+ +

load a single image from the open PShell data file.

+

the function can average over a region in the extra dimensions.

+
Parameters
+ + + + + + + + +
fileIDID of open HDF5 file from psh5_open_file().
datapathpath to the containing group in the HDF5 file. path separator is the slash "/".
datasetname of the dataset. also defines the name of the loaded wave.
dim2start2nd dimension coordinate of the first image set to 0 if dimension may not be present
dim2countnumber of subsequent images to average set to 1 if dimension may not be present
dim3start3rd dimension coordinate of the first image set to 0 if dimension may not be present
dim3countnumber of subsequent images to average set to 1 if dimension may not be present
+
+
+
Returns
name of loaded wave if successful. empty string otherwise.
+ +

Definition at line 1266 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_dataset_slabs()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_dataset_slabs (variable fileID,
string datapath,
string datasetname,
variable progress = defaultValue 
)
+
+ +

load a dataset slab-wise from the open PShell HDF5 file.

+

the function loads the dataset image by image using the hyperslab option.

+
Parameters
+ + + + + +
fileIDID of open HDF5 file from psh5_open_file().
datapathpath to the containing group in the HDF5 file. path separator is the slash "/".
datasetname of the dataset. also defines the name of the loaded wave.
progressselect whether a progress window is displayed during the process.
    +
  • 1 (default) show progress window.
  • +
  • 0 do not show progress window.
  • +
+
+
+
+
Returns
name of loaded wave if successful. empty string otherwise.
+ +

Definition at line 1130 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_info()

+ +
+
+ + + + + + + + + + + + + + + + + + +
string psh5_load_info (string APathName,
string AFileName 
)
+
+ +

load descriptive info from a PShell data file.

+

the info string lists the following information for each scan contained in the file:

    +
  • path of the scan group inside the file.
  • +
  • number of scan positions.
  • +
  • dataset names of scan positioners.
  • +
  • dataset names of detectors.
  • +
+
Parameters
+ + + +
APathNameigor symbolic path name. can be empty if the path is specified in AFileName or a dialog box should be displayed
AFileNameif empty a dialog box shows up
+
+
+
Returns
newline terminated string.
+ +

Definition at line 2349 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_preview()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_preview (string APathName,
string AFileName,
variable load_data = defaultValue,
variable load_attr = defaultValue,
string pref_scans = defaultValue,
string pref_datasets = defaultValue 
)
+
+ +

load a preview image from a PShell data file.

+

the data wave is loaded into the current data folder. attributes are loaded into the attr subfolder. existing waves in attr are deleted.

+
Parameters
+ + + + + + + +
APathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
AFileNameif empty a dialog box shows up
load_data1 (default): load data; 0: do not load data
load_attr1 (default): load attributes; 0: do not load attributes note: for correct scaling of the image, the attributes need to be loaded
pref_scanssemicolon-separated list of preferred scans. the items of the list are match strings for the Igor StringMatch function. the first matching scan (i.e. top-level HDF5 group with a matching name) is loaded from the file. if no match is found, the first scan is loaded.
pref_datasetssemicolon-separated list of preferred datasets. the items of the list are match strings for the Igor StringMatch function. the first matching dataset is loaded from the file. if no match is found, the first dataset listed in the file is loaded.
+
+
+
Returns
name of loaded preview wave.
+ +

Definition at line 250 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_reduced()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_reduced (string ANickName,
string APathName,
string AFileName,
funcref reduction_func,
string reduction_param,
variable progress = defaultValue,
variable nthreads = defaultValue 
)
+
+ +

load and reduce the ScientaImage dataset of the first scan of a PShell data file.

+

the resulting dataset is reduced in one image dimension by a user-defined reduction function, e.g. by region-of-interest integration, curve fitting, etc. cf. adh5_default_reduction for further details.

+

the function loads the dataset image by image using the hyperslab option and applies a custom reduction function to each image. the results from the reduction function are composed into one result wave. the raw data are discarded.

+

if the data is from the electron analyser driver and some special attributes are included, the function will set the scales of the image dimensions.

+

by default, the reduction function is called in separate threads to reduce the total loading time. (see the global variable psh5_perf_secs which reports the total run time of the function.) the effect varies depending on the balance between file loading (image size) and data processing (complexity of the reduction function). for debugging the reduction function, multi-threading can be disabled.

+
Parameters
+ + + + + + + + +
ANickNamedestination folder name (top level under root).
APathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed.
AFileNameif empty a dialog box shows up.
reduction_funccustom data reduction function. this can be any user-defined function which has the same parameters as adh5_default_reduction. some reduction functions are predefined in the PearlScientaPreprocess module.
reduction_paramparameter string for the reduction function.
progressprogress window.
    +
  • 1 (default) show progress window
  • +
  • 0 do not show progress window
  • +
+
nthreads
    +
  • -1 (default) use as many threads as there are processor cores (in addition to main thread).
  • +
  • 0 use main thread only (for debugging and profiling).
  • +
  • >= 1 use a fixed number of (additional) threads.
  • +
+
+
+
+
Returns
semicolon-separated list of the loaded dataset ReducedData1, ReducedData2, etc. if successful. auxiliary waves, scan positions, attributes are loaded but not listed in the string. empty string if an error occurred. error messages are printed to the history.
+
+global string s_filepath in new data folder contains the full file path on disk.
+
+global string s_scanpaths in new data folder contains a list of scan groups inside the file.
+ +

Definition at line 1893 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_scan_attrs()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_scan_attrs (variable fileID,
string scanpath,
variable attr_sets = defaultValue 
)
+
+ +

load attributes of a PShell scan group.

+

"attributes" are the auxiliary data inside the attrs group. do not confuse with HDF5 attributes! HDF5 attributes are loaded by the psh5_load_scan_meta() function.

+

data is loaded into the current data folder. this should normally be the :attr folder inside the respective scan folder.

+
Parameters
+ + + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
attr_setsspecify the attribute sets to be loaded. this value can be an arithmetic OR of the following constants. by default, all attributes are loaded.
    +
  • 1 all datasets that are present in the file.
  • +
  • 2 datasets relevant for wave scaling of Scienta data.
  • +
+
+
+
+
Returns
semicolon-separated list of the loaded waves.
+ +

Definition at line 553 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_scan_complete()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_scan_complete (variable fileID,
string scanpath,
variable load_data = defaultValue,
variable load_attr = defaultValue 
)
+
+ +

load all data of a selected scan from a PShell data file.

+

data is loaded into the current data folder. attribute datasets are loaded into sub-folder attr. region datasets are loaded into region sub-folders. existing data, if present, is overwritten.

+
Parameters
+ + + + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
load_dataselect whether datasets (positioners and detectors) are loaded.
    +
  • 1 (default) load data.
  • +
  • 0 do not load data.
  • +
+
load_attrselect whether attributes (auxiliary device readbacks) are loaded. for proper wave scaling, the attributes must be loaded.
    +
  • 1 (default) load attributes.
  • +
  • 0 do not load attributes.
  • +
+
+
+
+
Returns
semicolon-separated list of the loaded data waves (excluding attributes).
+ +

Definition at line 360 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_scan_data()

+ +
+
+ + + + + + + + + + + + + + + + + + +
string psh5_load_scan_data (variable fileID,
string scanpath 
)
+
+ +

load all datasets of a PShell scan group.

+

data is loaded into the current data folder. region datasets are loaded into the respective region sub-folders.

+

this function does not scale the datasets. call ps_scale_datasets() separately.

+
Parameters
+ + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
+
+
+
Returns
semicolon-separated list of the loaded waves.
+ +

Definition at line 513 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_scan_info()

+ +
+
+ + + + + + + + + + + + + + + + + + +
string psh5_load_scan_info (variable fileID,
string scanpath 
)
+
+ +

load descriptive info from a PShell scan.

+

the info string contains up to three lines which are made up of the following information:

    +
  • number of scan positions.
  • +
  • dataset names of scan positioners.
  • +
  • dataset names of detectors (without region names).
  • +
  • region names
  • +
+
Parameters
+ + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to scan group in the HDF5 file.
+
+
+
Returns
newline terminated string.
+ +

Definition at line 2396 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_scan_meta()

+ +
+
+ + + + + + + + + + + + + + + + + + +
string psh5_load_scan_meta (variable fileID,
string scanpath 
)
+
+ +

load metadata of a PShell scan group.

+

metadata are the HDF5 attributes attached to the scan group. the following attributes are loaded. the respective wave names under Igor are given in parentheses.

+
    +
  • Dimensions (ScanDimensions)
  • +
  • Writables (ScanWritables)
  • +
  • Readables (ScanReadables)
  • +
  • Steps (ScanSteps)
  • +
+

if they are missing in the file, ScanDimensions and ScanReadables are set to default values assuming the file contains a single spectrum.

+

data is loaded into the current data folder.

+
Parameters
+ + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
+
+
+
Returns
semicolon-separated list of the loaded waves.
+ +

Definition at line 621 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_scan_preview()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_scan_preview (variable fileID,
string scanpath,
variable set_scale = defaultValue,
string pref_datasets = defaultValue 
)
+
+ +

load a preview dataset from an open PShell HDF5 file.

+

if the dataset has a maximum of two dimensions, the function loads it at once. if it has more than two dimension, the function selects and loads one two-dimensional slab.

+
Parameters
+ + + + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
set_scaleby default, the function tries to set the wave scaling if the attributes have been loaded. if multiple datasets are loaded from a file, it is more efficient to set the scaling of all loaded datasets at the end by calling ps_scale_datasets().
    +
  • 1 (default) set the wave scaling.
  • +
  • 0 do not set the wave scaling.
  • +
+
pref_datasetssemicolon-separated list of preferred datasets. the items of the list are match strings for the Igor StringMatch function. the first matching dataset is loaded from the file. if no match is found, the first dataset listed in the file is loaded. if empty, a hard-coded default preference list is used.
+
+
+
Returns
name of loaded wave if successful. empty string otherwise.
+ +

Definition at line 822 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_load_scan_section()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string psh5_load_scan_section (variable fileID,
string scanpath,
variable dim,
variable set_scale = defaultValue,
string pref_datasets = defaultValue 
)
+
+ +

load a longitudinal section of a scan from an open PShell HDF5 file.

+

the dataset must have three dimensions.

+
Parameters
+ + + + + + +
fileIDID of open HDF5 file from psh5_open_file().
scanpathpath to the scan group in the HDF5 file, e.g. "/scan 1".
dimreserved, must be 0.
set_scaleby default, the function tries to set the wave scaling if the attributes have been loaded. if multiple datasets are loaded from a file, it is more efficient to set the scaling of all loaded datasets at the end by calling ps_scale_datasets().
    +
  • 1 (default) set the wave scaling.
  • +
  • 0 do not set the wave scaling.
  • +
+
pref_datasetssemicolon-separated list of preferred datasets. the items of the list are match strings for the Igor StringMatch function. the first matching dataset is loaded from the file. if no match is found, the first dataset listed in the file is loaded. if empty, a hard-coded default preference list is used.
+
+
+
Returns
name of loaded wave if successful. empty string otherwise.
+
Warning
EXPERIMENTAL: this function is under development.
+ +

Definition at line 935 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ psh5_open_file()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
variable psh5_open_file (string ANickName,
string APathName,
string AFileName 
)
+
+ +

open a HDF5 file created by the PShell data acquisition program and prepare the data folder.

+

the function opens a specified or interactively selected HDF5 file, creates a data folder $ANickName under root, and changes to the new data folder.

+

the file must be closed by psh5_close_file() after use.

+
Parameters
+ + + + +
ANickNamedestination folder name (top level under root).
APathNameigor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed
AFileNameif empty a dialog box shows up
+
+
+
Returns
ID of open HDF5 file from HDF5OpenFile. zero if an error occurred.
+
+global string s_filepath in new data folder contains the full file path on disk.
+
+global string s_scanpaths in new data folder contains a list of scan groups inside the file.
+ +

Definition at line 109 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ reduce_slab_image()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
static threadsafe wave reduce_slab_image (wave slabdata,
wave image,
funcref reduction_func,
string reduction_param 
)
+
+static
+
+ +

Definition at line 2323 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ reduce_slab_worker()

+ +
+
+ + + + + +
+ + + + + + + + +
static threadsafe variable reduce_slab_worker (funcref reduction_func)
+
+static
+
+ +

Definition at line 2284 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ select_dataset()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static string select_dataset (string file_datasets,
string pref_datasets 
)
+
+static
+
+ +

select the preferred dataset from a list of available datasets.

+
Parameters
+ + + +
file_datasetssemicolon-separated list of datasets that are available in the file. the items may include a path separated by slashes "/". only the last component of the path is checked.
pref_datasetssemicolon-separated list of preferred datasets. the items of the list are match strings for the Igor StringMatch function. the first matching dataset is loaded from the file. if no match is found, the first file dataset is selected.
+
+
+
Returns
selected dataset.
+ +

Definition at line 760 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ twave2list()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + +
static string twave2list (wave wt,
string sep 
)
+
+static
+
+ +

convert text wave to list.

+ +

Definition at line 2455 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ wave2list()

+ +
+
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
static string wave2list (wave w,
string format,
string sep 
)
+
+static
+
+ +

convert numeric wave to list.

+ +

Definition at line 2472 of file pearl-pshell-import.ipf.

+ +
+
+

Variable Documentation

+ +

◆ kAngleDimLabel

+ +
+
+ + + + +
const string kAngleDimLabel = "angle"
+
+ +

Dimension label for the angle dispersive dimension of multi-dimensional datasets.

+ +

Definition at line 67 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ kDataDimLabel

+ +
+
+ + + + +
const string kDataDimLabel = "data"
+
+ +

Dimension label for the data dimension.

+

This label may be used to store the parameters for the setscale d operation.

+ +

Definition at line 74 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ kDetectorSensitivity

+ +
+
+ + + + +
const variable kDetectorSensitivity = 4
+
+ +

multiply scienta detector intensity by this value to get actual counts.

+ +

Definition at line 86 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ kEnergyDimLabel

+ +
+
+ + + + +
const string kEnergyDimLabel = "energy"
+
+ +

Dimension label for the energy dispersive dimension of multi-dimensional datasets.

+ +

Definition at line 64 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ kPreviewDatasets

+ +
+
+ + + + +
const string kPreviewDatasets = "ScientaImage;ScientaSpectrum;ImageAngleDistribution;ImageEnergyDistribution;Counts;SampleCurrent;"
+
+ +

List of preferred datasets to load for preview.

+ +

Definition at line 77 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ kScanDimLabel

+ +
+
+ + + + +
const string kScanDimLabel = "scan"
+
+ +

Dimension label for the scan dimension of multi-dimensional datasets.

+ +

Definition at line 70 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ kScientaScalingDatasets

+ +
+
+ + + + +
const string kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;"
+
+ +

List of datasets that must be loaded to determine the axis scaling of a Scienta image.

+ +

Definition at line 80 of file pearl-pshell-import.ipf.

+ +
+
+ +

◆ kTransposedDatasets

+ +
+
+ + + + +
const string kTransposedDatasets = "ScientaImage;"
+
+ +

List of datasets that should be transposed upon loading.

+ +

Definition at line 83 of file pearl-pshell-import.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #pragma IgorVersion = 6.36
3 #pragma ModuleName = PearlPShellImport
4 #include <HDF5 Browser>
5 #include "pearl-gui-tools"
6 #include "pearl-area-import"
7 
8 // copyright (c) 2013-18 Paul Scherrer Institut
9 //
10 // Licensed under the Apache License, Version 2.0 (the "License");
11 // you may not use this file except in compliance with the License.
12 // You may obtain a copy of the License at
13 // http:///www.apache.org/licenses/LICENSE-2.0
14 
57 
62 
64 strconstant kEnergyDimLabel = "energy"
65 
67 strconstant kAngleDimLabel = "angle"
68 
70 strconstant kScanDimLabel = "scan"
71 
74 strconstant kDataDimLabel = "data"
75 
77 strconstant kPreviewDatasets = "ScientaImage;ScientaSpectrum;ImageAngleDistribution;ImageEnergyDistribution;Counts;SampleCurrent;"
78 
80 strconstant kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;"
81 
83 strconstant kTransposedDatasets = "ScientaImage;"
84 
86 constant kDetectorSensitivity = 4
87 
109 function psh5_open_file(ANickName, APathName, AFileName)
110  string ANickName
111  string APathName
112  string AFileName
113 
114  setdatafolder root:
115  newdatafolder /s /o $("root:" + ANickName)
116  dfref fileDF = GetDataFolderDFR()
117 
118  variable fileID
119  HDF5OpenFile /P=$APathName /R fileID as AFileName
120  if (v_flag == 0)
121  string /g s_filepath
122  string /g s_scanpaths
123  s_filepath = s_path + s_filename
124  s_scanpaths = psh5_list_scans(fileID)
125  else
126  fileID = 0
127  endif
128 
129  return fileID
130 end
131 
139 function psh5_close_file(fileID)
140  variable fileID
141 
142  HDF5CloseFile fileID
143 end
144 
169 function /s psh5_load_complete(ANickName, APathName, AFileName, [load_data, load_attr])
170  string ANickName
171  string APathName
172  string AFileName
173  variable load_data
174  variable load_attr
175 
176  if (ParamIsDefault(load_data))
177  load_data = 1
178  endif
179  if (ParamIsDefault(load_attr))
180  load_attr = 1
181  endif
182 
183  dfref saveDF = GetDataFolderDFR()
184 
185  // performance monitoring
186  variable timerRefNum
187  variable /g psh5_perf_secs
188  timerRefNum = startMSTimer
189 
190  variable fileID = psh5_open_file(ANickName, APathName, AFileName)
191  if (fileID)
192  dfref fileDF = GetDataFolderDFR()
193  svar s_filepath
194  svar s_scanpaths
195  AFileName = s_filepath
196  print "loading " + s_filepath + "\r"
197 
198  variable ig
199  variable ng = ItemsInList(s_scanpaths, ";")
200  string sg
201  string folder
202 
203  for (ig = 0; ig < ng; ig += 1)
204  sg = StringFromList(ig, s_scanpaths, ";")
205  folder = ReplaceString("/", sg, "")
206  folder = ReplaceString(" ", folder, "")
207  folder = CleanupName(folder, 0)
208  setdatafolder fileDF
209  newdatafolder /s /o $folder
210  psh5_load_scan_complete(fileID, sg, load_data=load_data, load_attr=load_attr)
211  endfor
212 
213  psh5_close_file(fileID)
214  else
215  AFileName = ""
216  endif
217 
218  psh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
219 
220  setdatafolder saveDF
221  return AFileName
222 end
223 
250 function /s psh5_load_preview(APathName, AFileName, [load_data, load_attr, pref_scans, pref_datasets])
251  string APathName
252  string AFileName
253  variable load_data
254  variable load_attr
255  string pref_scans
256  string pref_datasets
257 
258  if (ParamIsDefault(load_data))
259  load_data = 1
260  endif
261  if (ParamIsDefault(load_attr))
262  load_attr = 1
263  endif
264  if (ParamIsDefault(pref_scans))
265  pref_scans = "*scan1*;"
266  endif
267  if (ParamIsDefault(pref_datasets))
268  pref_datasets = ""
269  endif
270 
271  dfref saveDF = GetDataFolderDFR()
272 
273  variable fileID
274  string scanpaths = ""
275  string dataname = ""
276 
277  // performance monitoring
278  variable timerRefNum
279  variable /g adh5_perf_secs
280  timerRefNum = startMSTimer
281 
282  HDF5OpenFile /P=$APathName /R /Z fileID as AFileName
283  if (v_flag == 0)
284  AFileName = s_path + s_filename
285  dfref fileDF = GetDataFolderDFR()
286 
287  scanpaths = psh5_list_scans(fileID)
288  variable ng = ItemsInList(scanpaths)
289  variable ig
290  string sg
291  variable np = ItemsInList(pref_scans)
292  variable ip
293  string sp
294  variable found = 0
295  if (ng > 0)
296  for (ip = 0; ip < np; ip += 1)
297  for (ig = 0; ig < ng; ig += 1)
298  sg = StringFromList(ig, scanpaths)
299  sp = StringFromList(ip, pref_scans)
300  if (StringMatch(sg, sp))
301  found = 1
302  break
303  endif
304  endfor
305  if (found)
306  break
307  endif
308  endfor
309  if (!found)
310  ig = 0
311  endif
312  sg = StringFromList(ig, scanpaths)
313 
314  if (load_attr)
315  setdatafolder fileDF
316  newdatafolder /o/s attr
317  killwaves /a/z
318  psh5_load_scan_attrs(fileID, sg)
319  endif
320 
321  setdatafolder fileDF
322  dataname = psh5_load_scan_preview(fileID, sg, set_scale=load_attr, pref_datasets=pref_datasets)
323  else
324  print "no scans found in file " + AFileName
325  endif
326 
327  HDF5CloseFile fileID
328  endif
329 
330  if (timerRefNum >= 0)
331  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
332  endif
333 
334  setdatafolder saveDF
335  return dataname
336 end
337 
360 function /s psh5_load_scan_complete(fileID, scanpath, [load_data, load_attr])
361  variable fileID
362  string scanpath
363  variable load_data
364  variable load_attr
365 
366  if (ParamIsDefault(load_data))
367  load_data = 1
368  endif
369  if (ParamIsDefault(load_attr))
370  load_attr = 1
371  endif
372 
373  dfref saveDF = GetDataFolderDFR()
374 
375  dfref dataDF = GetDataFolderDFR()
376  string wavenames
377  string attrnames
378  psh5_load_scan_meta(fileID, scanpath)
379  if (load_attr)
380  newdatafolder /s /o attr
381  attrnames = psh5_load_scan_attrs(fileID, scanpath)
382  endif
383  if (load_data)
384  setdatafolder dataDF
385  wavenames = psh5_load_scan_data(fileID, scanpath)
386  endif
387  if (load_data && load_attr)
388  setdatafolder dataDF
389  ps_scale_datasets()
390  endif
391 
392  setdatafolder saveDF
393  return wavenames
394 end
395 
404 function /s psh5_list_scans(fileID)
405  variable fileID
406 
407  HDF5ListGroup /F /TYPE=1 fileID, "/"
408 
409  variable ig
410  variable ng = ItemsInList(S_HDF5ListGroup, ";")
411  string sg
412  string scans = ""
413 
414  for (ig = 0; ig < ng; ig += 1)
415  sg = StringFromList(ig, S_HDF5ListGroup, ";")
416  if (cmpstr(sg[1,4], "scan") == 0)
417  scans = AddListItem(sg, scans, ";", inf)
418  endif
419  endfor
420 
421  return scans
422 end
423 
439 function /s psh5_list_scan_datasets(fileID, scanpath, [include_regions])
440  variable fileID
441  string scanpath
442  variable include_regions
443 
444  if (ParamIsDefault(include_regions))
445  include_regions = 0
446  endif
447  string result
448 
449  HDF5ListGroup /TYPE=2 /Z fileID, scanpath
450  result = S_HDF5ListGroup
451 
452  if (include_regions)
453  HDF5ListGroup /R /TYPE=2 /Z fileID, scanpath
454  variable n = ItemsInList(S_HDF5ListGroup)
455  variable i
456  string ds
457  string region_datasets
458  for (i = 0; i < n; i += 1)
459  ds = StringFromList(i, S_HDF5ListGroup)
460  if (StringMatch(ds, "region*/*"))
461  //region_datasets = psh5_list_scan_datasets(fileID, ReplaceString("//", scanpath + "/" + region, "/"), include_regions=0)
462  result = AddListItem(ds, result, ";", inf)
463  endif
464  endfor
465  endif
466 
467  return result
468 end
469 
480 function /s psh5_list_scan_regions(fileID, scanpath)
481  variable fileID
482  string scanpath
483 
484  HDF5ListGroup /TYPE=1 /Z fileID, scanpath
485  variable n = ItemsInList(S_HDF5ListGroup)
486  variable i
487  string result = ""
488  string s
489  for (i = 0; i < n; i += 1)
490  s = StringFromList(i, S_HDF5ListGroup)
491  if (StringMatch(s, "region*"))
492  result = AddListItem(s, result, ";", inf)
493  endif
494  endfor
495 
496  return result
497 end
498 
513 function /s psh5_load_scan_data(fileID, scanpath)
514  variable fileID
515  string scanpath
516 
517  string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
518  variable nds = ItemsInList(datasets)
519  variable ids
520  string sds
521  string sw
522  string wavenames = ""
523  for (ids = 0; ids < nds; ids += 1)
524  sds = StringFromList(ids, datasets)
525  sw = psh5_load_dataset(fileID, scanpath, sds, set_scale=0)
526  wavenames = AddListItem(sw, wavenames, ";", inf)
527  endfor
528 
529  return wavenames
530 end
531 
553 function /s psh5_load_scan_attrs(fileID, scanpath, [attr_sets])
554  variable fileID
555  string scanpath
556  variable attr_sets
557 
558  if (ParamIsDefault(attr_sets))
559  attr_sets = 1
560  endif
561 
562  string attr_path = ReplaceString("//", scanpath + "/attrs", "/")
563  string attr_list = ""
564  if (attr_sets & 1)
565  HDF5ListGroup /TYPE=2 /Z fileID, attr_path
566  if (!v_flag)
567  attr_list = S_HDF5ListGroup
568  endif
569  endif
570 
571  variable ids
572  variable nds
573  string sds
574 
575  if (attr_sets & 2)
576  nds = ItemsInList(kScientaScalingDatasets, ";")
577  for (ids = 0; ids < nds; ids += 1)
578  sds = StringFromList(ids, kScientaScalingDatasets)
579  if (WhichListItem(sds, attr_list) < 0)
580  attr_list = AddListItem(sds, attr_list, ";", inf)
581  endif
582  endfor
583  endif
584 
585  nds = ItemsInList(attr_list, ";")
586  string wavenames = ""
587  for (ids = 0; ids < nds; ids += 1)
588  sds = StringFromList(ids, attr_list, ";")
589  HDF5LoadData /O /Q /Z fileID, attr_path + "/" + sds
590  if (!v_flag)
591  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
592  endif
593  endfor
594  wavenames = ReplaceString(";;", wavenames, ";")
595 
596  return wavenames
597 end
598 
621 function /s psh5_load_scan_meta(fileID, scanpath)
622  variable fileID
623  string scanpath
624  string wavenames = ""
625 
626  HDF5LoadData /O /Q /Z /A="Dimensions" /N=ScanDimensions /TYPE=1 fileID, scanpath
627  if (!v_flag)
628  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
629  else
630  make /n=1 /o ScanDimensions
631  ScanDimensions = 0
632  wavenames = AddListItem("ScanDimensions", wavenames, ";", inf)
633  endif
634  HDF5LoadData /O /Q /Z /A="Readables" /N=ScanReadables /TYPE=1 fileID, scanpath
635  if (!v_flag)
636  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
637  else
638  make /n=1 /o /t ScanReadables
639  ScanReadables[0] = "ScientaSpectrum"
640  wavenames = AddListItem("ScanReadables", wavenames, ";", inf)
641  endif
642  HDF5LoadData /O /Q /Z /A="Writables" /N=ScanWritables /TYPE=1 fileID, scanpath
643  if (!v_flag)
644  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
645  endif
646  HDF5LoadData /O /Q /Z /A="Steps" /N=ScanSteps /TYPE=1 fileID, scanpath
647  if (!v_flag)
648  wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
649  endif
650  wavenames = ReplaceString(";;", wavenames, ";")
651 
652  return wavenames
653 end
654 
688 function /s psh5_load_dataset(fileID, scanpath, datasetname, [set_scale])
689  variable fileID
690  string scanpath
691  string datasetname
692  variable set_scale
693 
694  if (ParamIsDefault(set_scale))
695  set_scale = 1
696  endif
697 
698  dfref base_df = GetDataFolderDFR()
699 
700  string datasetpath
701  datasetpath = scanpath + "/" + datasetname
702  datasetpath = ReplaceString("//", datasetpath, "/")
703 
704  string regionname
705  string regionpath
706  if (ItemsInList(datasetname, "/") >= 2)
707  regionname = StringFromList(0, datasetname, "/")
708  regionpath = ReplaceString("//", scanpath + "/" + regionname, "/")
709  datasetname = RemoveListItem(0, datasetname, "/")
710  NewDataFolder /o/s $regionname
711  else
712  regionname = ""
713  regionpath = scanpath
714  endif
715 
716  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
717  InitHDF5DataInfo(di)
718  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
719  if (err != 0)
720  print "error accessing detector/data"
721  return ""
722  endif
723 
724  string dataname
725  if (di.ndims < 2)
726  HDF5LoadData /O /Q /Z fileID, datasetpath
727  dataname = StringFromList(0, S_waveNames)
728  else
729  dataname = psh5_load_dataset_slabs(fileID, regionpath, datasetname)
730  endif
731 
732  wave /z data = $dataname
733  if (waveexists(data))
734  psh5_load_dataset_meta(fileID, regionpath, datasetname, data)
735  ps_set_dimlabels(data)
736  if (set_scale)
737  ps_scale_dataset(data)
738  endif
739  else
740  dataname = ""
741  endif
742 
743  setdatafolder base_df
744  return dataname
745 end
746 
760 static function /s select_dataset(file_datasets, pref_datasets)
761  string file_datasets
762  string pref_datasets
763 
764  variable index
765  variable nds = ItemsInList(file_datasets)
766  variable ids
767  string sds = ""
768  string mds = ""
769  variable np = ItemsInList(pref_datasets)
770  variable ip
771  string sp
772  variable found = 0
773  if (nds > 0)
774  for (ip = 0; ip < np; ip += 1)
775  for (ids = 0; ids < nds; ids += 1)
776  sds = StringFromList(ids, file_datasets)
777  index = ItemsInList(sds, "/") - 1
778  mds = StringFromList(index, sds, "/")
779  sp = StringFromList(ip, pref_datasets)
780  if (StringMatch(mds, sp))
781  found = 1
782  break
783  endif
784  endfor
785  if (found)
786  break
787  endif
788  endfor
789  if (!found)
790  ids = 0
791  sds = StringFromList(ids, file_datasets)
792  endif
793  endif
794 
795  return sds
796 end
797 
822 function /s psh5_load_scan_preview(fileID, scanpath, [set_scale, pref_datasets])
823  variable fileID
824  string scanpath
825  variable set_scale
826  string pref_datasets
827 
828  if (ParamIsDefault(set_scale))
829  set_scale = 1
830  endif
831  if (ParamIsDefault(pref_datasets) || (strlen(pref_datasets) == 0))
832  pref_datasets = kPreviewDatasets
833  endif
834 
835  dfref saveDF = GetDataFolderDFR()
836  dfref dataDF = saveDF
837 
838  string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
839  string datasetname = select_dataset(datasets, pref_datasets)
840  string datasetpath
841  datasetpath = scanpath + "/" + datasetname
842  datasetpath = ReplaceString("//", datasetpath, "/")
843 
844  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
845  InitHDF5DataInfo(di)
846  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
847  if (err != 0)
848  print "error accessing detector/data"
849  return ""
850  endif
851 
852  string dataname
853  if (di.ndims < 2)
854  HDF5LoadData /O /Q /Z fileID, datasetpath
855  dataname = StringFromList(0, S_waveNames)
856  wave /z data = $dataname
857  if (waveexists(data))
858  ps_set_dimlabels(data)
859  endif
860  else
861  variable dim2start = 0
862  variable dim2count = 1
863  variable dim3start = 0
864  variable dim3count = 1
865  if (di.ndims >= 3)
866  dim2start = floor(di.dims[2] / 2)
867  dim2count = 1
868  endif
869  if (di.ndims >= 4)
870  dim3start = floor(di.dims[3] / 2)
871  dim3count = 1
872  endif
873 
874  dataname = psh5_load_dataset_slab(fileID, scanpath, datasetname, dim2start, dim2count, dim3start, dim3count)
875  endif
876 
877  wave /z data = $dataname
878  if (waveexists(data))
879  if (set_scale)
880  setdatafolder dataDF
881  string positioners
882  string positioner
883  string positionerpath
884  positioners = psh5_load_scan_meta(fileID, scanpath)
885  wave /t /z ScanWritables
886  if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
887  positioner = ScanWritables[0]
888  if (strlen(positioner) > 0)
889  positionerpath = scanpath + "/" + positioner
890  positionerpath = ReplaceString("//", positionerpath, "/")
891  HDF5LoadData /O /Q /Z fileID, positionerpath
892  endif
893  endif
894 
895  setdatafolder dataDF
896  newdatafolder /o/s attr
897  psh5_load_scan_attrs(fileID, scanpath, attr_sets=2)
898  setdatafolder dataDF
899  ps_scale_dataset(data)
900  endif
901  else
902  dataname = ""
903  endif
904 
905  return dataname
906 end
907 
935 function /s psh5_load_scan_section(fileID, scanpath, dim, [set_scale, pref_datasets])
936  variable fileID
937  string scanpath
938  variable dim
939  variable set_scale
940  string pref_datasets
941 
942  // select first dimension (future argument)
943  // 0 = first dimension is x axis (energy of scienta image)
944  dim = 0
945 
946  if (ParamIsDefault(set_scale))
947  set_scale = 1
948  endif
949  if (ParamIsDefault(pref_datasets) || (strlen(pref_datasets) == 0))
950  pref_datasets = kPreviewDatasets
951  endif
952 
953  dfref saveDF = GetDataFolderDFR()
954  dfref dataDF = saveDF
955 
956  string datasets = psh5_list_scan_datasets(fileID, scanpath)
957  string datasetname = select_dataset(datasets, pref_datasets)
958  string datasetpath
959  datasetpath = scanpath + "/" + datasetname
960  datasetpath = ReplaceString("//", datasetpath, "/")
961  string dataname = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
962  string destname = dataname[0,29] + num2str(dim)
963 
964  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
965  InitHDF5DataInfo(di)
966  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
967  if (err != 0)
968  print "error accessing detector/data"
969  return ""
970  elseif (di.ndims != 3)
971  print "error: rank of dataset != 3"
972  return ""
973  endif
974 
975  variable idx, idy, idz, idt
976  variable transpose = WhichListItem(dataname, kTransposedDatasets) >= 0
977  if (transpose)
978  idx = 1
979  idy = 0
980  else
981  idx = 0
982  idy = 1
983  endif
984  idz = 2
985  idt = 3
986 
987  variable nx, ny, nz
988  nx = di.dims[idx]
989  ny = di.dims[idy]
990  nz = di.dims[idz]
991 
992  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
993  wave slab
994  slab[][%Start] = 0
995  slab[][%Stride] = 1
996  slab[][%Count] = 1
997  slab[][%Block] = 1
998 
999  if (dim == 0)
1000  slab[idy][%Start] = floor(ny / 2)
1001  slab[idx][%Block] = nx
1002  make /n=(nx,nz) /o $destname
1003  else
1004  slab[idx][%Start] = floor(nx / 2)
1005  slab[idy][%Block] = ny
1006  make /n=(ny,nz) /o $destname
1007  endif
1008  slab[idz][%Block] = nz
1009  wave data = $destname
1010  data = 0
1011 
1012  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
1013  if (!v_flag)
1014  wave slabdata
1015  if (transpose)
1016  data += slabdata[0][p][q][0]
1017  else
1018  data += slabdata[p][0][q][0]
1019  endif
1020  endif
1021  killwaves /z slab, slabdata
1022 
1023  if (set_scale)
1024  make /n=(1,1,1) /free dummy
1025  ps_set_dimlabels2(dummy, dataname)
1026  setdimlabel 0, -1, $GetDimLabel(dummy, dim, -1), data
1027  setdimlabel 1, -1, $kScanDimLabel, data
1028 
1029  setdatafolder dataDF
1030  string positioners
1031  string positioner
1032  string positionerpath
1033  positioners = psh5_load_scan_meta(fileID, scanpath)
1034  wave /t /z ScanWritables
1035  if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
1036  positioner = ScanWritables[0]
1037  if (strlen(positioner) > 0)
1038  positionerpath = scanpath + "/" + positioner
1039  positionerpath = ReplaceString("//", positionerpath, "/")
1040  HDF5LoadData /O /Q /Z fileID, positionerpath
1041  endif
1042  endif
1043 
1044  setdatafolder dataDF
1045  newdatafolder /o/s attr
1046  killwaves /a/z
1047  psh5_load_scan_attrs(fileID, scanpath, attr_sets=2)
1048  setdatafolder dataDF
1049  ps_scale_dataset(data)
1050  endif
1051 
1052  return destname
1053 end
1054 
1073 function psh5_load_dataset_meta(fileID, datapath, datasetname, datawave)
1074  variable fileID
1075  string datapath
1076  string datasetname
1077  wave datawave
1078 
1079  dfref saveDF = GetDataFolderDFR()
1080  SetDataFolder NewFreeDataFolder()
1081 
1082  string datasetpath = datapath + "/" + datasetname
1083  datasetpath = ReplaceString("//", datasetpath, "/")
1084  string wnote
1085 
1086  HDF5LoadData /O /Q /Z /A="Writable Dimension" /N=WriteDim fileID, datasetpath
1087  if (!v_flag)
1088  wave WriteDim
1089  // scan dimension starts at 1
1090  sprintf wnote, "ScanDimension=%u", WriteDim[0]
1091  Note datawave, wnote
1092  endif
1093 
1094  HDF5LoadData /O /Q /Z /A="Writable Index" /N=WriteIndex fileID, datasetpath
1095  if (!v_flag)
1096  wave WriteIndex
1097  sprintf wnote, "WriteableIndex=%u", WriteIndex[0]
1098  Note datawave, wnote
1099  endif
1100 
1101  HDF5LoadData /O /Q /Z /A="Readable Index" /N=ReadIndex fileID, datasetpath
1102  if (!v_flag)
1103  wave ReadIndex
1104  sprintf wnote, "ReadableIndex=%u", ReadIndex[0]
1105  Note datawave, wnote
1106  endif
1107 
1108  setdatafolder saveDF
1109  return 0
1110 end
1111 
1130 function /s psh5_load_dataset_slabs(fileID, datapath, datasetname, [progress])
1131  variable fileID
1132  string datapath
1133  string datasetname
1134  variable progress
1135 
1136  if (ParamIsDefault(progress))
1137  progress = 1
1138  endif
1139 
1140  variable result = 0
1141  string datasetpath
1142  string datawavename
1143  datasetpath = datapath + "/" + datasetname
1144  datasetpath = ReplaceString("//", datasetpath, "/")
1145  datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
1146 
1147  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
1148  InitHDF5DataInfo(di)
1149  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
1150  if (err != 0)
1151  print "error accessing detector/data"
1152  return ""
1153  endif
1154  if (di.ndims < 2)
1155  print "error: rank of dataset < 2"
1156  return ""
1157  elseif (di.ndims < 3)
1158  progress = 0
1159  endif
1160 
1161  variable idx, idy, idz, idt, izt
1162  variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
1163  if (transpose)
1164  idx = 1
1165  idy = 0
1166  else
1167  idx = 0
1168  idy = 1
1169  endif
1170  idz = 2
1171  idt = 3
1172 
1173  variable nx, ny, nz, nt, nzt
1174  nx = di.dims[idx]
1175  ny = di.dims[idy]
1176  nz = di.dims[idz]
1177  nt = di.dims[idt]
1178  make /n=(nx,ny,nz,nt) /o $datawavename
1179  wave data = $datawavename
1180 
1181  nz = max(nz, 1)
1182  nt = max(nt, 1)
1183  nzt = nz * nt
1184  izt = 0
1185  if (progress)
1186  display_progress_panel("HDF5 Import", "Loading data...", nzt)
1187  endif
1188 
1189  // load data image by image
1190  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
1191  wave slab
1192  slab[][%Start] = 0
1193  slab[][%Stride] = 1
1194  slab[][%Count] = 1
1195  slab[][%Block] = 1
1196  slab[idx][%Block] = nx
1197  slab[idy][%Block] = ny
1198 
1199  variable iz, it
1200  for (iz = 0; iz < nz; iz += 1)
1201  for (it = 0; it < nt; it += 1)
1202  slab[idz][%Start] = iz
1203  slab[idt][%Start] = it
1204  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
1205  wave slabdata // 2D, 3D, or 4D with singletons
1206  if (transpose)
1207  data[][][iz][it] = slabdata[q][p][0][0]
1208  else
1209  data[][][iz][it] = slabdata[p][q][0][0]
1210  endif
1211 
1212  // progress window
1213  izt += 1
1214  if (progress)
1215  if (update_progress_panel(izt))
1216  result = -4 // user abort
1217  break
1218  endif
1219  endif
1220  endfor
1221  if (result < 0)
1222  break
1223  endif
1224  endfor
1225 
1226  if (progress)
1227  kill_progress_panel()
1228  endif
1229 
1230  killwaves /z slab, slabdata
1231  if (!result)
1232  ps_set_dimlabels(data)
1233  return datawavename
1234  else
1235  killwaves /z data
1236  return ""
1237  endif
1238 end
1239 
1266 function /s psh5_load_dataset_slab(fileID, datapath, datasetname, dim2start, dim2count, dim3start, dim3count)
1267  variable fileID
1268  string datapath
1269  string datasetname
1270  variable dim2start
1271  variable dim2count
1272  variable dim3start
1273  variable dim3count
1274 
1275  string datasetpath
1276  string datawavename
1277  datasetpath = datapath + "/" + datasetname
1278  datasetpath = ReplaceString("//", datasetpath, "/")
1279  datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
1280 
1281  STRUCT HDF5DataInfo di
1282  InitHDF5DataInfo(di)
1283  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
1284  if (err != 0)
1285  print "error accessing detector/data"
1286  return ""
1287  endif
1288  if (di.ndims < 2)
1289  print "error: rank of dataset < 2"
1290  return ""
1291  endif
1292 
1293  variable idx, idy, idz, idt
1294  variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
1295  if (transpose)
1296  idx = 1
1297  idy = 0
1298  else
1299  idx = 0
1300  idy = 1
1301  endif
1302  idz = 2
1303  idt = 3
1304 
1305  variable nx, ny
1306  nx = di.dims[idx]
1307  ny = di.dims[idy]
1308  make /n=(nx,ny) /o $datawavename
1309  wave data = $datawavename
1310  data = 0
1311 
1312  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
1313  wave slab
1314  slab[][%Start] = 0
1315  slab[][%Stride] = 1
1316  slab[][%Count] = 1
1317  slab[][%Block] = 1
1318  slab[idx][%Block] = nx
1319  slab[idy][%Block] = ny
1320 
1321  variable iz, it
1322  variable navg = 0
1323  variable dim2end = dim2start + dim2count - 1
1324  variable dim3end = dim3start + dim3count - 1
1325  for (iz = dim2start; iz <= dim2end; iz += 1)
1326  for (it = dim3start; it <= dim3end; it += 1)
1327  slab[idz][%Start] = iz
1328  slab[idt][%Start] = it
1329  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
1330  if (!v_flag)
1331  wave slabdata
1332  if (transpose)
1333  data += slabdata[q][p][0][0]
1334  else
1335  data += slabdata[p][q][0][0]
1336  endif
1337  navg += 1
1338  endif
1339  endfor
1340  endfor
1341  if (navg)
1342  data /= navg
1343  endif
1344 
1345  killwaves /z slab, slabdata
1346  ps_set_dimlabels(data)
1347  return datawavename
1348 end
1349 
1365 function ps_set_dimlabels(data)
1366  wave data
1367 
1368  ps_set_dimlabels2(data, NameOfWave(data))
1369 end
1370 
1384 function ps_set_dimlabels2(data, name)
1385  wave data
1386  string name
1387 
1388  variable dummy
1389  try
1390  // intrinsic dimensions
1391  strswitch(name)
1392  case "ScientaImage":
1393  setdimlabel 0, -1, $kEnergyDimLabel, data
1394  setdimlabel 1, -1, $kAngleDimLabel, data
1395  if (WaveDims(data) >= 3)
1396  setdimlabel 2, -1, $kScanDimLabel, data
1397  endif
1398  AbortOnRTE
1399  break
1400  case "ImageAngleDistribution":
1401  case "ScientaAngleDistribution":
1402  if (WaveDims(data) >= 2)
1403  setdimlabel 0, -1, $kScanDimLabel, data
1404  setdimlabel 1, -1, $kAngleDimLabel, data
1405  else
1406  setdimlabel 0, -1, $kAngleDimLabel, data
1407  endif
1408  AbortOnRTE
1409  break
1410  case "ScientaSpectrum":
1411  case "ImageEnergyDistribution":
1412  case "ScientaEnergyDistribution":
1413  if (WaveDims(data) >= 2)
1414  setdimlabel 0, -1, $kScanDimLabel, data
1415  setdimlabel 1, -1, $kEnergyDimLabel, data
1416  else
1417  setdimlabel 0, -1, $kEnergyDimLabel, data
1418  endif
1419  AbortOnRTE
1420  break
1421  default:
1422  if (WaveDims(data) == 1)
1423  setdimlabel 0, -1, $kScanDimLabel, data
1424  AbortOnRTE
1425  else
1426  return 1
1427  endif
1428  endswitch
1429  catch
1430  dummy = GetRTError(1)
1431  return 2
1432  endtry
1433  return 0
1434 end
1435 
1441 static function /df find_scan_folder(dataDF)
1442  dfref dataDF
1443 
1444  dfref attrDF = dataDF:attr
1445  if (!DataFolderRefStatus(attrDF))
1446  string df = GetDataFolder(1, dataDF) + ":"
1447  dfref scanDF = $df
1448  else
1449  dfref scanDF = dataDF
1450  endif
1451  return scanDF
1452 end
1453 
1458 static function /df find_attr_folder(dataDF)
1459  dfref dataDF
1460 
1461  dfref attrDF = dataDF:attr
1462  if (!DataFolderRefStatus(attrDF))
1463  string df = GetDataFolder(1, dataDF) + ":"
1464  dfref scanDF = $df
1465  dfref attrDF = scanDF:attr
1466  endif
1467  return attrDF
1468 end
1469 
1486 function ps_scale_datasets()
1487  dfref scanDF = GetDataFolderDFR()
1488  dfref attrDF = find_attr_folder(scanDF)
1489 
1490  make /n=3 /free lo, hi
1491  make /n=3 /t /free ax, un
1492  wave /t /z /SDFR=scanDF ScanReadables
1493  if (WaveExists(ScanReadables))
1494  variable isr
1495  variable nsr = numpnts(ScanReadables)
1496  string ssr
1497  string sdf
1498  for (isr = 0; isr < nsr; isr += 1)
1499  setdatafolder scanDF
1500  ssr = ScanReadables[isr]
1501  if (ItemsInList(ssr, "/") >= 2)
1502  sdf = StringFromList(0, ssr, "/")
1503  ssr = RemoveListItem(0, ssr, "/")
1504  setdatafolder $sdf
1505  endif
1506  wave /z wsr=$ssr
1507  if (WaveExists(wsr))
1508  ps_detect_scale(ax, lo, hi, un)
1509  ps_scale_dataset_2(wsr, ax, lo, hi, un)
1510  endif
1511  endfor
1512  endif
1513  setdatafolder scanDF
1514 end
1515 
1532 function ps_scale_dataset(data)
1533  wave data
1534 
1535  dfref saveDF = GetDataFolderDFR()
1536  dfref dataDF = GetWavesDataFolderDFR(data)
1537 
1538  setdatafolder dataDF
1539  make /n=3 /free lo, hi
1540  make /n=3 /t /free ax, un
1541  ps_detect_scale(ax, lo, hi, un)
1542  ps_scale_dataset_2(data, ax, lo, hi, un)
1543  setdatafolder saveDF
1544 end
1545 
1546 static function /wave find_scale_wave(name, dataDF, scanDF, attrDF)
1547  string name
1548  dfref dataDF
1549  dfref scanDF
1550  dfref attrDF
1551 
1552  wave /SDFR=dataDF /Z w = $name
1553  if (!WaveExists(w))
1554  wave /SDFR=scanDF /Z w = $name
1555  if (!WaveExists(w))
1556  wave /SDFR=attrDF /Z w = $name
1557  endif
1558  endif
1559  return w
1560 end
1561 
1603 function ps_detect_scale(ax, lo, hi, un)
1604  wave /t ax
1605  wave lo
1606  wave hi
1607  wave /t un
1608 
1609  dfref dataDF = GetDataFolderDFR()
1610  dfref scanDF = find_scan_folder(dataDF)
1611  dfref attrDF = find_attr_folder(dataDF)
1612 
1613  redimension /n=4 lo, hi, un, ax
1614  setdimlabel 0, 0, $kEnergyDimLabel, lo, hi, un, ax
1615  setdimlabel 0, 1, $kAngleDimLabel, lo, hi, un, ax
1616  setdimlabel 0, 2, $kScanDimLabel, lo, hi, un, ax
1617  setdimlabel 0, 3, $kDataDimLabel, lo, hi, un, ax
1618 
1619  // default values
1620  lo[%$kEnergyDimLabel] = 0
1621  hi[%$kEnergyDimLabel] = 1
1622  un[%$kEnergyDimLabel] = "eV"
1623  ax[%$kEnergyDimLabel] = "Ekin"
1624 
1625  lo[%$kAngleDimLabel] = -1
1626  hi[%$kAngleDimLabel] = 1
1627  un[%$kAngleDimLabel] = "arb."
1628  un[%$kAngleDimLabel] = "slice"
1629 
1630  lo[%$kScanDimLabel] = 0
1631  hi[%$kScanDimLabel] = 1
1632  un[%$kScanDimLabel] = "arb."
1633  ax[%$kScanDimLabel] = "scan"
1634 
1635  lo[%$kDataDimLabel] = 0
1636  hi[%$kDataDimLabel] = 0
1637  un[%$kDataDimLabel] = "arb."
1638  ax[%$kDataDimLabel] = "value"
1639 
1640  wave /SDFR=attrDF /T /Z LensMode
1641  wave /Z ChannelBegin = find_scale_wave("ScientaChannelBegin", dataDF, scanDF, attrDF)
1642  wave /Z ChannelEnd = find_scale_wave("ScientaChannelEnd", dataDF, scanDF, attrDF)
1643  wave /Z SliceBegin = find_scale_wave("ScientaSliceBegin", dataDF, scanDF, attrDF)
1644  wave /Z SliceEnd = find_scale_wave("ScientaSliceEnd", dataDF, scanDF, attrDF)
1645 
1646  // lens mode can give more detail
1647  if (waveexists(LensMode) && (numpnts(LensMode) >= 1))
1648  strswitch(LensMode[0])
1649  case "Angular45":
1650  lo[%$kAngleDimLabel] = -45/2
1651  hi[%$kAngleDimLabel] = +45/2
1652  un[%$kAngleDimLabel] = "°"
1653  ax[%$kAngleDimLabel] = "angle"
1654  break
1655  case "Angular60":
1656  lo[%$kAngleDimLabel] = -60/2
1657  hi[%$kAngleDimLabel] = +60/2
1658  un[%$kAngleDimLabel] = "°"
1659  ax[%$kAngleDimLabel] = "angle"
1660  break
1661  case "Transmission":
1662  un[%$kAngleDimLabel] = "arb."
1663  ax[%$kAngleDimLabel] = "offset"
1664  break
1665  endswitch
1666  endif
1667 
1668  // best option if scales are explicit in separate waves
1669  if (waveexists(ChannelBegin) && waveexists(ChannelEnd) && (numpnts(ChannelBegin) >= 1) && (numpnts(ChannelEnd) >= 1))
1670  lo[%$kEnergyDimLabel] = ChannelBegin[0]
1671  hi[%$kEnergyDimLabel] = ChannelEnd[0]
1672  endif
1673  if (waveexists(SliceBegin) && waveexists(SliceEnd) && (numpnts(SliceBegin) >= 1) && (numpnts(SliceEnd) >= 1))
1674  lo[%$kAngleDimLabel] = SliceBegin[0]
1675  hi[%$kAngleDimLabel] = SliceEnd[0]
1676  endif
1677 
1678  wave /z /t /SDFR=scanDF ScanWritables
1679  if (WaveExists(ScanWritables))
1680  wave /z /SDFR=scanDF scanner = $ScanWritables[0]
1681  if (!WaveExists(scanner))
1682  wave /z /SDFR=attrDF scanner = $ScanWritables[0]
1683  endif
1684  if (WaveExists(scanner) && (numpnts(scanner) >= 1))
1685  lo[%$kScanDimLabel] = scanner[0]
1686  hi[%$kScanDimLabel] = scanner[numpnts(scanner)-1]
1687  ax[%$kScanDimLabel] = NameOfWave(scanner)
1688  strswitch(NameOfWave(scanner))
1689  case "Eph":
1690  ax[%$kScanDimLabel] = "photon energy"
1691  un[%$kScanDimLabel] = "eV"
1692  break
1693  case "ManipulatorX":
1694  case "ManipulatorY":
1695  case "ManipulatorZ":
1696  case "FocusYTrans":
1697  case "FocusZTrans":
1698  case "RefocusYTrans":
1699  case "RefocusZTrans":
1700  case "ExitSlitY":
1701  un[%$kScanDimLabel] = "mm"
1702  break
1703  case "ExitSlit":
1704  un[%$kScanDimLabel] = "µm"
1705  break
1706  case "ManipulatorTheta":
1707  case "ManipulatorTilt":
1708  case "ManipulatorPhi":
1709  un[%$kScanDimLabel] = "°"
1710  break
1711  case "FocusXRot":
1712  case "FocusYRot":
1713  case "FocusZRot":
1714  case "RefocusXRot":
1715  case "RefocusYRot":
1716  case "RefocusZRot":
1717  un[%$kScanDimLabel] = "mrad"
1718  break
1719  endswitch
1720  endif
1721  endif
1722 end
1723 
1763 function ps_scale_dataset_2(data, ax, lo, hi, un)
1764  wave data
1765  wave /t ax
1766  wave lo
1767  wave hi
1768  wave /t un
1769 
1770  string snote = note(data)
1771  string sdim
1772  sdim = GetDimLabel(data, 0, -1)
1773  if (strlen(sdim))
1774  setscale /i x lo[%$sdim], hi[%$sdim], un[%$sdim], data
1775  snote = ReplaceStringByKey("AxisLabelX", snote, ax[%$sdim], "=", "\r")
1776  endif
1777 
1778  sdim = GetDimLabel(data, 1, -1)
1779  if (strlen(sdim))
1780  setscale /i y lo[%$sdim], hi[%$sdim], un[%$sdim], data
1781  snote = ReplaceStringByKey("AxisLabelY", snote, ax[%$sdim], "=", "\r")
1782  endif
1783 
1784  sdim = GetDimLabel(data, 2, -1)
1785  if (strlen(sdim))
1786  setscale /i z lo[%$sdim], hi[%$sdim], un[%$sdim], data
1787  snote = ReplaceStringByKey("AxisLabelZ", snote, ax[%$sdim], "=", "\r")
1788  endif
1789 
1790  string data_unit = un[%$kDataDimLabel]
1791  string data_label = ax[%$kDataDimLabel]
1792  string s
1793  variable def = (cmpstr(data_unit, "arb.") == 0) && (cmpstr(data_label, "value") == 0)
1794 
1795  if (def)
1796  s = StringByKey("AxisLabelD", snote, "=", "\r")
1797  if (strlen(s) > 0)
1798  data_label = s
1799  def = 0
1800  endif
1801  s = StringByKey("AxisUnitD", snote, "=", "\r")
1802  if (strlen(s) > 0)
1803  data_unit = s
1804  def = 0
1805  endif
1806  endif
1807 
1808  if (def)
1809  strswitch(NameOfWave(data))
1810  case "ScientaImage":
1811  case "ImageAngleDistribution":
1812  case "ScientaAngleDistribution":
1813  case "ScientaSpectrum":
1814  case "ImageEnergyDistribution":
1815  case "ScientaEnergyDistribution":
1816  data *= kDetectorSensitivity
1817  data_unit = "counts"
1818  data_label = "intensity"
1819  def = 0
1820  break
1821  case "SampleCurrent":
1822  case "RefCurrent":
1823  case "AuxCurrent":
1824  data_unit = "A"
1825  data_label = "current"
1826  def = 0
1827  break
1828  case "MachineCurrent":
1829  data_unit = "mA"
1830  data_label = "current"
1831  def = 0
1832  break
1833  endswitch
1834  endif
1835 
1836  setscale d 0, 0, data_unit, data
1837  snote = ReplaceStringByKey("AxisLabelD", snote, data_label, "=", "\r")
1838  snote = ReplaceStringByKey("AxisUnitD", snote, data_unit, "=", "\r")
1839  snote = ReplaceStringByKey("Dataset", snote, NameOfWave(data), "=", "\r")
1840  note /k data, snote
1841 end
1842 
1893 function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [progress, nthreads])
1894  string ANickName
1895  string APathName
1896  string AFileName
1897  funcref adh5_default_reduction reduction_func
1898  string reduction_param
1899  variable progress
1900  variable nthreads
1901 
1902  if (ParamIsDefault(progress))
1903  progress = 1
1904  endif
1905  if (ParamIsDefault(nthreads))
1906  nthreads = -1
1907  endif
1908 
1909  dfref saveDF = GetDataFolderDFR()
1910 
1911  // performance monitoring
1912  variable timerRefNum
1913  variable /g psh5_perf_secs
1914  timerRefNum = startMSTimer
1915 
1916  variable fileID = psh5_open_file(ANickName, APathName, AFileName)
1917  string wavenames = ""
1918  if (fileID)
1919  dfref fileDF = GetDataFolderDFR()
1920  svar s_filepath
1921  svar s_scanpaths
1922  AFileName = s_filepath
1923  print "loading " + s_filepath + "\r"
1924 
1925  variable ig = 0
1926  variable ng = ItemsInList(s_scanpaths)
1927  string scanpath
1928  string folder
1929  string positioners
1930  string positioner
1931  string positionerpath
1932 
1933  scanpath = StringFromList(ig, s_scanpaths)
1934  folder = ReplaceString("/", scanpath, "")
1935  folder = ReplaceString(" ", folder, "")
1936  folder = CleanupName(folder, 0)
1937  setdatafolder fileDF
1938  newdatafolder /s /o $folder
1939  dfref dataDF = GetDataFolderDFR()
1940  positioners = psh5_load_scan_meta(fileID, scanpath)
1941  newdatafolder /s /o attr
1942  killwaves /a/z
1943  psh5_load_scan_attrs(fileID, scanpath)
1944  setdatafolder dataDF
1945  wave /t /z ScanWritables
1946  if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
1947  positioner = ScanWritables[0]
1948  if (strlen(positioner) > 0)
1949  positionerpath = scanpath + "/" + positioner
1950  positionerpath = ReplaceString("//", positionerpath, "/")
1951  HDF5LoadData /O /Q /Z fileID, positionerpath
1952  endif
1953  endif
1954 
1955  setdatafolder dataDF
1956  string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
1957  string dataset = select_dataset(datasets, "ScientaImage")
1958  wavenames = psh5_load_dataset_reduced(fileID, scanpath, dataset, reduction_func, reduction_param, progress=progress, nthreads=nthreads)
1959 
1960  psh5_close_file(fileID)
1961  endif
1962 
1963  if (timerRefNum >= 0)
1964  psh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
1965  endif
1966 
1967  setdatafolder saveDF
1968  return wavenames
1969 end
1970 
1971 
2022 function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_func, reduction_param, [progress, nthreads])
2023  variable fileID
2024  string scanpath
2025  string datasetname
2026  funcref adh5_default_reduction reduction_func
2027  string reduction_param
2028  variable progress
2029  variable nthreads
2030 
2031  if (ParamIsDefault(progress))
2032  progress = 1
2033  endif
2034  if (ParamIsDefault(nthreads))
2035  nthreads = -1
2036  endif
2037 
2038  dfref base_df = GetDataFolderDFR()
2039  variable result = 0
2040  string datasetpath
2041  string datawavename
2042  string wavenames = ""
2043 
2044  datasetpath = scanpath + "/" + datasetname
2045  datasetpath = ReplaceString("//", datasetpath, "/")
2046  datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
2047 
2048  string regionname
2049  string regionpath
2050  if (ItemsInList(datasetname, "/") >= 2)
2051  regionname = StringFromList(0, datasetname, "/")
2052  regionpath = ReplaceString("//", scanpath + "/" + regionname, "/")
2053  datasetname = RemoveListItem(0, datasetname, "/")
2054  NewDataFolder /o/s $regionname
2055  else
2056  regionname = ""
2057  regionpath = scanpath
2058  endif
2059 
2060  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
2061  InitHDF5DataInfo(di)
2062  variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
2063  if (err != 0)
2064  print "error accessing detector/data"
2065  result = -1
2066  return wavenames
2067  endif
2068  if (di.ndims < 2)
2069  print "error: rank of dataset < 2"
2070  result = -2
2071  return wavenames
2072  elseif (di.ndims < 3)
2073  progress = 0
2074  endif
2075 
2076  variable idx, idy, idz, idt
2077  variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
2078  if (transpose)
2079  idx = 1
2080  idy = 0
2081  else
2082  idx = 0
2083  idy = 1
2084  endif
2085  idz = 2
2086  idt = 3
2087 
2088  variable nx, ny, nz, nt, nzt
2089  nx = di.dims[idx]
2090  ny = di.dims[idy]
2091  nz = di.dims[idz]
2092  nt = di.dims[idt]
2093  // adjust singleton dimensions
2094  nz = max(nz, 1)
2095  nt = max(nt, 1)
2096  nzt = nz * nt
2097 
2098  // load data image by image
2099  HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
2100  wave slab
2101  slab[][%Start] = 0
2102  slab[][%Stride] = 1
2103  slab[][%Count] = 1
2104  slab[][%Block] = 1
2105  slab[idx][%Block] = nx
2106  slab[idy][%Block] = ny
2107 
2108  // set up multi threading
2109  if (nthreads < 0)
2110  nthreads = ThreadProcessorCount
2111  endif
2112  if (nthreads > 0)
2113  variable threadGroupID = ThreadGroupCreate(nthreads)
2114  variable ithread
2115  for (ithread = 0; ithread < nthreads; ithread += 1)
2116  ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
2117  endfor
2118  else
2119  make /n=(nzt) /df /free processing_folders
2120  endif
2121 
2122  if (progress)
2123  display_progress_panel("HDF5 Import", "Loading data (step 1 of 2)...", nzt)
2124  endif
2125 
2126  // create a template wave with the correct scales and labels
2127  make /n=(nx,ny) /d /o $datawavename
2128  wave template = $datawavename
2129  ps_set_dimlabels2(template, datawavename)
2130  ps_scale_dataset(template)
2131 
2132  variable iz, it, izt
2133  string dfname
2134  variable iw, nw
2135  string sw
2136  make /n=0 /free /wave result_waves
2137 
2138  izt = 0
2139  for (iz = 0; iz < nz; iz += 1)
2140  for (it = 0; it < nt; it += 1)
2141  // load hyperslab
2142  slab[idz][%Start] = iz
2143  slab[idt][%Start] = it
2144  dfname = "processing_" + num2str(izt)
2145  newdatafolder /s $dfname
2146  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
2147 
2148  // send to processing queue
2149  duplicate template, image
2150  variable /g r_index = iz
2151  variable /g s_index = it
2152  string /g func_param = reduction_param
2153 
2154  if (nthreads > 0)
2155  WaveClear image
2156  ThreadGroupPutDF threadGroupID, :
2157  else
2158  processing_folders[izt] = GetDataFolderDFR()
2159  make /n=1/d profile1, profile2
2160  wave slabdata
2161  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
2162  variable /g func_result = numpnts(reduced_waves)
2163  adh5_get_result_waves(reduced_waves, "redw_", 0)
2164  WaveClear slabdata, image, reduced_waves
2165  setdatafolder ::
2166  endif
2167 
2168  izt += 1
2169  // progress window
2170  if (progress)
2171  if (update_progress_panel(izt))
2172  print "user abort"
2173  result = -4
2174  break
2175  endif
2176  endif
2177  endfor
2178  endfor
2179 
2180  killwaves /z slab, slabdata, template
2181  if (progress)
2182  update_progress_panel(0, message="Processing data (step 2 of 2)...")
2183  endif
2184 
2185  dfref dfr
2186  for (izt = 0; (izt < nzt) && (result == 0); izt += 1)
2187  if (nthreads > 0)
2188  do
2189  if (progress)
2190  if (update_progress_panel(izt))
2191  print "user abort"
2192  result = -4
2193  break
2194  endif
2195  endif
2196  dfr = ThreadGroupGetDFR(threadGroupID, 1000)
2197  if (DatafolderRefStatus(dfr) != 0)
2198  break
2199  endif
2200  while (1)
2201  else
2202  if (progress)
2203  if (update_progress_panel(izt))
2204  print "user abort"
2205  result = -4
2206  break
2207  endif
2208  endif
2209  dfr = processing_folders[izt]
2210  endif
2211 
2212  if (result != 0)
2213  break
2214  endif
2215 
2216  nvar rr = dfr:r_index
2217  nvar ss = dfr:s_index
2218  nvar func_result = dfr:func_result
2219 
2220  if (func_result < 1)
2221  print "error during data reduction."
2222  result = -3
2223  break
2224  endif
2225 
2226  if (numpnts(result_waves) == 0)
2227  redimension /n=(func_result) result_waves
2228  for (iw = 0; iw < func_result; iw += 1)
2229  sw = "redw_" + num2str(iw)
2230  wave profile = dfr:$sw
2231  sw = "ReducedData" + num2str(iw+1)
2232  make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
2233  wave data = $sw
2234  setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
2235  setdimlabel 1, -1, $kScanDimLabel, data
2236  note data, note(profile)
2237  ps_scale_dataset(data)
2238  setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
2239  setscale d 0, 0, waveunits(profile, -1), data
2240  result_waves[iw] = data
2241  endfor
2242  endif
2243  for (iw = 0; iw < func_result; iw += 1)
2244  sw = "redw_" + num2str(iw)
2245  wave profile = dfr:$sw
2246  wave data = result_waves[iw]
2247  data[][rr][ss] = profile[p]
2248  endfor
2249  endfor
2250 
2251  if (nthreads > 0)
2252  variable tstatus = ThreadGroupRelease(threadGroupID)
2253  if (tstatus == -2)
2254  print "error: thread did not terminate properly."
2255  result = -5
2256  endif
2257  else
2258  for (izt = 0; izt < nzt; izt += 1)
2259  KillDataFolder /Z processing_folders[izt]
2260  endfor
2261  endif
2262 
2263  if (result == 0)
2264  nw = numpnts(result_waves)
2265  wavenames = ""
2266  for (iw = 0; iw < nw; iw += 1)
2267  wave data = result_waves[iw]
2268  if (nz == 1)
2269  redimension /n=(-1, 0, 0) data
2270  elseif (nt == 1)
2271  redimension /n=(-1, nz, 0) data
2272  endif
2273  wavenames += nameofwave(data) + ";"
2274  endfor
2275  endif
2276  if (progress)
2277  kill_progress_panel()
2278  endif
2279 
2280  setdatafolder base_df
2281  return wavenames
2282 end
2283 
2284 threadsafe static function reduce_slab_worker(reduction_func)
2285  funcref adh5_default_reduction reduction_func
2286  do
2287  // wait for job from main thread
2288  do
2289  dfref dfr = ThreadGroupGetDFR(0, 1000)
2290  if (DataFolderRefStatus(dfr) == 0)
2291  if (GetRTError(2))
2292  return 0 // no more jobs
2293  endif
2294  else
2295  break
2296  endif
2297  while (1)
2298 
2299  // get input data
2300  wave slabdata = dfr:slabdata
2301  wave image = dfr:image
2302  svar func_param = dfr:func_param
2303  nvar rr = dfr:r_index
2304  nvar ss = dfr:s_index
2305 
2306  // do the work
2307  newdatafolder /s outDF
2308  variable /g r_index = rr
2309  variable /g s_index = ss
2310  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
2311  variable /g func_result = numpnts(reduced_waves)
2312 
2313  // send output to queue and clean up
2314  adh5_get_result_waves(reduced_waves, "redw_", 0)
2315  WaveClear slabdata, image, reduced_waves
2316  ThreadGroupPutDF 0, :
2317  KillDataFolder dfr
2318  while (1)
2319 
2320  return 0
2321 end
2322 
2323 threadsafe static function /wave reduce_slab_image(slabdata, image, reduction_func, reduction_param)
2324  wave slabdata
2325  wave image
2326  funcref adh5_default_reduction reduction_func
2327  string reduction_param
2328 
2329  // the multiplication by detector sensitivity assumes that we are loading a ScientaImage.
2330  image = slabdata[q][p][0][0] * kDetectorSensitivity
2331 
2332  return reduction_func(image, reduction_param)
2333 end
2334 
2349 function /s psh5_load_info(APathName, AFileName)
2350  string APathName
2351  string AFileName
2352 
2353  dfref saveDF = GetDataFolderDFR()
2354  dfref fileDF = NewFreeDataFolder()
2355  setdatafolder fileDF
2356 
2357  variable fileID
2358  string filepath
2359  string scanpaths
2360  variable nscans
2361  variable iscan
2362  string scanpath
2363  string info = ""
2364 
2365  HDF5OpenFile /P=$APathName /R fileID as AFileName
2366  if (v_flag == 0)
2367  filepath = s_path + s_filename
2368  scanpaths = psh5_list_scans(fileID)
2369  nscans = ItemsInList(scanpaths)
2370  for (iscan = 0; iscan < nscans; iscan += 1)
2371  scanpath = StringFromList(iscan, scanpaths)
2372  info = info + scanpath + "\r"
2373  info = info + psh5_load_scan_info(fileID, scanpath)
2374  endfor
2375  HDF5CloseFile fileID
2376  endif
2377 
2378  setdatafolder saveDF
2379  return info
2380 end
2381 
2396 function /s psh5_load_scan_info(fileID, scanpath)
2397  variable fileID
2398  string scanpath
2399 
2400  string info = ""
2401  string positions = ""
2402  string positioners = ""
2403  string readables = ""
2404  string detectors = ""
2405  string regions = ""
2406 
2407  psh5_load_scan_meta(fileID, scanpath)
2408 
2409  wave /z ScanDimensions
2410  wave /t /z ScanWritables
2411  wave /t /z ScanReadables
2412  wave /z ScanSteps
2413 
2414  if (WaveExists(ScanSteps) && (numpnts(ScanSteps) >= 1))
2415  ScanSteps += 1
2416  positions = "positions = (" + wave2list(ScanSteps, "%u", ",") + ")"
2417  info = AddListItem(positions, info, "\r", inf)
2418  endif
2419  if (WaveExists(ScanWritables) && (numpnts(ScanWritables) >= 1))
2420  positioners = "positioners = " + twave2list(ScanWritables, ",")
2421  info = AddListItem(positioners, info, "\r", inf)
2422  endif
2423 
2424  variable i, m, n
2425  string s
2426  if (WaveExists(ScanReadables) && (numpnts(ScanReadables) >= 1))
2427  readables = twave2list(ScanReadables, ",")
2428  n = ItemsInList(readables, ",")
2429  for (i = 0; i < n; i += 1)
2430  s = StringFromList(i, readables, ",")
2431  m = ItemsInList(s, "/")
2432  if (m > 1)
2433  s = StringFromList(m - 1, s, "/")
2434  endif
2435  if (WhichListItem(s, detectors, ",") < 0)
2436  detectors = AddListItem(s, detectors, ",", inf)
2437  endif
2438  endfor
2439  detectors = "detectors = " + detectors
2440  info = AddListItem(detectors, info, "\r", inf)
2441  endif
2442 
2443  regions = psh5_list_scan_regions(fileID, scanpath)
2444  if (strlen(regions) > 0)
2445  regions = "regions = " + regions
2446  info = AddListItem(regions, info, "\r", inf)
2447  endif
2448 
2449  return info
2450 end
2451 
2455 static function /s twave2list(wt, sep)
2456  wave /t wt
2457  string sep
2458 
2459  string list = ""
2460  variable n = numpnts(wt)
2461  variable i
2462  for (i = 0; i < n; i += 1)
2463  list = AddListItem(wt[i], list, sep, inf)
2464  endfor
2465 
2466  return list
2467 end
2468 
2472 static function /s wave2list(w, format, sep)
2473  wave w
2474  string format
2475  string sep
2476 
2477  string list = ""
2478  variable n = numpnts(w)
2479  variable i
2480  string s
2481  for (i = 0; i < n; i += 1)
2482  sprintf s, format, w[i]
2483  list = AddListItem(s, list, sep, inf)
2484  endfor
2485 
2486  return list
2487 end
const string kEnergyDimLabel
Dimension label for the energy dispersive dimension of multi-dimensional datasets.
+
string psh5_load_scan_preview(variable fileID, string scanpath, variable set_scale=defaultValue, string pref_datasets=defaultValue)
load a preview dataset from an open PShell HDF5 file.
+
string psh5_load_scan_attrs(variable fileID, string scanpath, variable attr_sets=defaultValue)
load attributes of a PShell scan group.
+
const string kTransposedDatasets
List of datasets that should be transposed upon loading.
+
string psh5_load_scan_complete(variable fileID, string scanpath, variable load_data=defaultValue, variable load_attr=defaultValue)
load all data of a selected scan from a PShell data file.
+
const string kScanDimLabel
Dimension label for the scan dimension of multi-dimensional datasets.
+
const string kAngleDimLabel
Dimension label for the angle dispersive dimension of multi-dimensional datasets. ...
+
const string kDataDimLabel
Dimension label for the data dimension.
+
string psh5_load_preview(string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue, string pref_scans=defaultValue, string pref_datasets=defaultValue)
load a preview image from a PShell data file.
+
variable psh5_open_file(string ANickName, string APathName, string AFileName)
open a HDF5 file created by the PShell data acquisition program and prepare the data folder...
+
variable ps_scale_datasets()
set the dimension scales of loaded PShell Scienta datasets according to attributes.
+
string psh5_load_scan_meta(variable fileID, string scanpath)
load metadata of a PShell scan group.
+
const string kScientaScalingDatasets
List of datasets that must be loaded to determine the axis scaling of a Scienta image.
+
string psh5_list_scan_datasets(variable fileID, string scanpath, variable include_regions=defaultValue)
list datasets of a PShell scan group.
+
string psh5_load_scan_data(variable fileID, string scanpath)
load all datasets of a PShell scan group.
+
const variable kDetectorSensitivity
multiply scienta detector intensity by this value to get actual counts.
+
string psh5_load_complete(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
load everything from a PShell data file.
+
string psh5_list_scans(variable fileID)
list scan groups of a PShell data file.
+
variable psh5_close_file(variable fileID)
close a HDF5 file opened by psh5_open_file.
+
const string kPreviewDatasets
List of preferred datasets to load for preview.
+
+
+Namespaces | +Functions
-
pearl-scienta-preprocess.ipf File Reference
+
pearl-scienta-preprocess.ipf File Reference
+

preprocessing functions for Scienta detector images. +More...

+
#include "pearl-fitfuncs"
+

Go to the source code of this file.

+ + + + + +

+Namespaces

 PearlScientaPreprocess
 preprocessing functions for Scienta detector images.
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Functions

variable prompt_int_linbg_reduction (string *param)
 prompt the user for integrate on linear background reduction parameters. More...
 
string capture_int_linbg_cursors ()
 this function is for testing only, until we implement a proper interface More...
 
string csr_int_linbg_reduction (string win)
 set reduction parameters from cursors in a graph. More...
 
threadsafe wave int_linbg_reduction (wave source, string *param)
 linear-background subtracted integration reduction function. More...
 
variable prompt_int_quadbg_reduction (string *param)
 
threadsafe wave int_quadbg_reduction (wave source, string *param)
 integrate peak area minus a quadratic background More...
 
variable prompt_redim_linbg_reduction (string *param)
 parameter dialog for the redim_linbg_reduction() function More...
 
threadsafe wave redim_linbg_reduction (wave source, string *param)
 linear background reduction function for incorrectly dimensioned scienta image More...
 
variable test_gauss4_reduction (wave image)
 apply the gauss4_reduction function to a single image More...
 
variable prompt_gauss4_reduction (string *param)
 prompt for the gauss4_reduction parameters More...
 
threadsafe wave gauss4_reduction (wave source, string *param)
 fit horizontal cuts of an image with up to four gaussian peaks on a linear background More...
 
+

Detailed Description

+

preprocessing functions for Scienta detector images.

+

this procedure contains functions for data reduction and instrument-specific normalization.

+
Author
matthias muntwiler, matth.nosp@m.ias..nosp@m.muntw.nosp@m.iler.nosp@m.@psi..nosp@m.ch
+ + +

Definition in file pearl-scienta-preprocess.ipf.

+

Function Documentation

+ +

◆ capture_int_linbg_cursors()

+ +
+
+ + + + + + + +
string capture_int_linbg_cursors ()
+
+ +

this function is for testing only, until we implement a proper interface

+ +

Definition at line 67 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ csr_int_linbg_reduction()

+ +
+
+ + + + + + + + +
string csr_int_linbg_reduction (string win)
+
+ +

set reduction parameters from cursors in a graph.

+

PRELIMINARY - function arguments may change

+

sets reduction parameters from cursors in a graph. an even number of cursors (2 or more) must be set on the image. cursor names and order do not matter, except that the alphabetically first cursor which is attached to an image selects the image. the cursors mark the following positions, from innermost to outermost pair: 1) low and high limits of peak region. 2) peak-side boundary of lower and upper background region. 3) lower and upper cropping region.

+ +

Definition at line 89 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ gauss4_reduction()

+ +
+
+ + + + + + + + + + + + + + + + + + +
threadsafe wave gauss4_reduction (wave source,
string * param 
)
+
+ +

fit horizontal cuts of an image with up to four gaussian peaks on a linear background

+

the function fits each horizontal profile (EDC) with four gaussian peaks on a linear background. the position and width of the peaks is kept fixed according to input parameters. the peak amplitude is constrained to positive value.

+

the width parameter is defined as in Igor's gauss curve fit function (standard deviation divided by the square root of two). the return value in dest1 is the integrated peak of one of the peaks. dest2 returns the corresponding error estimate.

+
Parameters
+ + + +
sourcesource wave. two-dimensional distribution of counts. for correct weighting and error estimation it is important that the source wave contains actual counts (Poisson statistics).
param(in, out) semicolon-separated key=value list of processing parameters. this is a pass-by-reference argument. the following parameters are required. position, width and limit parameters are on the x (energy) scale.
    +
  • rngl low limit of fit interval
  • +
  • rngh high limit of fit interval
  • +
  • pos1 position of peak 1
  • +
  • wid1 width of peak 1
  • +
  • pos2 position of peak 2
  • +
  • wid2 width of peak 2
  • +
  • pos3 position of peak 3
  • +
  • wid3 width of peak 3
  • +
  • pos4 position of peak 4
  • +
  • wid4 width of peak 4
  • +
  • npeaks number of peaks to fit: 1...4 the others are held at amplitude 0.
  • +
  • ybox box size of averaging in y direction, must be 1 or 3. other values lead to corrupt data.
  • +
+
+
+
+
Returns
free wave containing references of the result waves. the number of waves is two times the number of peaks that are fit. the first npeaks waves contain the peak integrals, the second npeaks waves the corresponding error estimates.
+ +

Definition at line 672 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ int_linbg_reduction()

+ +
+
+ + + + + + + + + + + + + + + + + + +
threadsafe wave int_linbg_reduction (wave source,
string * param 
)
+
+ +

linear-background subtracted integration reduction function.

+

data reduction function for adh5_load_reduced_detector. cf. adh5_default_reduction for an explanation of reduction functions.

+

this function calculates the average pixel value of each angular slice in one center and two background intervals. a background value is calculated at the center position by linear interpolation from the two background values. returns the center minus linear background in dest1. returns the Poisson one-sigma error in dest2.

+

typical values (peak centered on detector, FWHM ~ 20 % of image) Lcrop=0.11;Hcrop=0.11;Lsize=0.2;Hsize=0.2;Cpos=0.5;Csize=0.2

+
Parameters
+ + + +
sourcescienta detector image, energy axis along X, angle axis along Y. two-dimensional intensity distribution (image). the scales are carried over to the result waves.
paramparameters in a key1=value1;key2=value2;... list. all region parameters are relative to the image size (0...1).
    +
  • Lcrop = size of the lower cropping region
  • +
  • Hcrop = size of the upper cropping region
  • +
  • Lsize = size of the lower background integration region
  • +
  • Hsize = size of the upper background integration region
  • +
  • Cpos = center position of the of the peak integration region
  • +
  • Csize = size of the peak integration region
  • +
+
+
+
+
Returns
free wave containing references of the two result waves. the first wave is the integral minus linear background. the second wave is the Poisson one-sigma error.
+ +

Definition at line 214 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ int_quadbg_reduction()

+ +
+
+ + + + + + + + + + + + + + + + + + +
threadsafe wave int_quadbg_reduction (wave source,
string * param 
)
+
+ +

integrate peak area minus a quadratic background

+

data reduction function for adh5_load_reduced_detector. cf. adh5_default_reduction for an explanation of reduction functions.

+

this function calculates the average pixel value of each angular slice in one center and two background intervals. a background value is calculated at the center position by linear interpolation from the two background values. returns the center minus linear background in dest1. returns the Poisson one-sigma error in dest2.

+

typical values (peak centered on detector, FWHM ~ 20 % of image) Lcrop=0.11;Hcrop=0.11;Lsize=0.2;Hsize=0.2;Cpos=0.5;Csize=0.2

+
Parameters
+ + + +
sourcescienta detector image, energy axis along X, angle axis along Y. two-dimensional intensity distribution (image). the scales are carried over to the result waves.
paramparameters in a key1=value1;key2=value2;... list. all region parameters are relative to the image size (0...1).
    +
  • Lcrop = size of the lower cropping region
  • +
  • Hcrop = size of the upper cropping region
  • +
  • Lsize = size of the lower background integration region
  • +
  • Hsize = size of the upper background integration region
  • +
  • Cpos = center position of the of the peak integration region
  • +
  • Csize = size of the peak integration region
  • +
+
+
+
+
Returns
free wave containing references of the two result waves. the first wave is the integral minus linear background. the second wave is the Poisson one-sigma error.
+ +

Definition at line 367 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ prompt_gauss4_reduction()

+ +
+
+ + + + + + + + +
variable prompt_gauss4_reduction (string * param)
+
+ +

prompt for the gauss4_reduction parameters

+ +

Definition at line 580 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ prompt_int_linbg_reduction()

+ +
+
+ + + + + + + + +
variable prompt_int_linbg_reduction (string * param)
+
+ +

prompt the user for integrate on linear background reduction parameters.

+ +

Definition at line 35 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ prompt_int_quadbg_reduction()

+ +
+
+ + + + + + + + +
variable prompt_int_quadbg_reduction (string * param)
+
+ +

Definition at line 305 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ prompt_redim_linbg_reduction()

+ +
+
+ + + + + + + + +
variable prompt_redim_linbg_reduction (string * param)
+
+ +

parameter dialog for the redim_linbg_reduction() function

+
Parameters
+ + +
paramparameter string in a key1=value1;key2=value2;... list. the parameter string is passed by reference. see redim_linbg_reduction() for a description of parameters.
+
+
+
Returns
zero if the user clicked OK, non-zero if the user clicked Cancel.
+ +

Definition at line 463 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ redim_linbg_reduction()

+ +
+
+ + + + + + + + + + + + + + + + + + +
threadsafe wave redim_linbg_reduction (wave source,
string * param 
)
+
+ +

linear background reduction function for incorrectly dimensioned scienta image

+

if the energy step size does not divide the energy range to an integer number, the scienta image is exported with the wrong array size. this can be fixed by redimensioning the array.

+

the current implementation works in the case where dimension 0 needs to be incremented. the function may be generalized to dimension 1 and/or decrementing by additional parameters. it is not known yet whether a generalization is needed or whether it can cover all cases.

+

background subtraction and peak integration is the same as by the int_linbg_reduction() function.

+
Parameters
+ + + +
sourcesource wave Scienta detector image, energy axis along X, angle axis along Y
paramparameter string in a key1=value1;key2=value2;... list. the parameter string is passed by reference.
+
+
+

all region parameters are relative to the image size (0...1).

    +
  • Lcrop size of the lower cropping region
  • +
  • Hcrop size of the upper cropping region
  • +
  • Lsize size of the lower background integration region
  • +
  • Hsize size of the upper background integration region
  • +
  • Cpos center position of the of the peak integration region
  • +
  • Csize size of the peak integration region
  • +
+

typical values (peak centered on detector, FWHM ~ 20 % of image) Lcrop=0.11;Hcrop=0.11;Lsize=0.2;Hsize=0.2;Cpos=0.5;Csize=0.2

+
Returns
free wave containing references of the two result waves. the first wave is the integral minus linear background. the second wave is the Poisson one-sigma error.
+ +

Definition at line 526 of file pearl-scienta-preprocess.ipf.

+ +
+
+ +

◆ test_gauss4_reduction()

+ +
+
+ + + + + + + + +
variable test_gauss4_reduction (wave image)
+
+ +

apply the gauss4_reduction function to a single image

+

useful for testing or manual processing. to debug, (temporarily) remove the threadsafe attribute from the gauss2_reduction function.

+ +

Definition at line 546 of file pearl-scienta-preprocess.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #pragma IgorVersion = 6.1
3 #pragma ModuleName = PearlScientaPreprocess
4 #include "pearl-fitfuncs"
5 
6 // Copyright (c) 2013-18 Paul Scherrer Institut
7 //
8 // Licensed under the Apache License, Version 2.0 (the "License");
9 // you may not use this file except in compliance with the License.
10 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
12 
27 
32 
35 function prompt_int_linbg_reduction(param)
36  string &param
37 
38  variable Lcrop = NumberByKey("Lcrop", param, "=", ";")
39  variable Lsize = NumberByKey("Lsize", param, "=", ";")
40  variable Hcrop = NumberByKey("Hcrop", param, "=", ";")
41  variable Hsize = NumberByKey("Hsize", param, "=", ";")
42  variable Cpos = NumberByKey("Cpos", param, "=", ";")
43  variable Csize = NumberByKey("Csize", param, "=", ";")
44 
45  prompt Lcrop, "Lower cropping region"
46  prompt Hcrop, "Upper cropping region"
47  prompt Lsize, "Lower background region"
48  prompt Hsize, "Upper background region"
49  prompt Cpos, "Center position"
50  prompt Csize, "Center integration region"
51 
52  doprompt "int_linbg_reduction Parameters", lcrop, hcrop, lsize, hsize, cpos, csize
53  if (v_flag == 0)
54  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
55  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
56  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
57  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
58  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
59  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
60  endif
61 
62  return v_flag
63 end
64 
67 function /s capture_int_linbg_cursors()
68  string param = csr_int_linbg_reduction("")
69  svar /z global_params = root:packages:pearl_explorer:s_reduction_params
70  if (svar_exists(global_params))
71  global_params = param
72  endif
73  return param
74 end
75 
89 function /s csr_int_linbg_reduction(win)
90  string win
91 
92  // read all cursor positions
93  variable ic
94  string sc
95  variable nc = 10
96  make /n=(nc) /free positions
97  variable np = 0
98  wave /z image = $""
99  string imagename = ""
100  string tracename = ""
101  string info
102 
103  for (ic = 0; ic < nc; ic += 1)
104  sc = num2char(char2num("A") + ic)
105  wave /z wc = CsrWaveRef($sc, win)
106  info = CsrInfo($sc, win)
107  tracename = StringByKey("TNAME", info, ":", ";")
108  if (waveexists(wc) && (wavedims(wc) == 2))
109  if (!waveexists(image))
110  wave image = wc
111  imagename = tracename
112  endif
113  if (cmpstr(tracename, imagename) == 0)
114  positions[np] = pcsr($sc, win)
115  np += 1
116  endif
117  endif
118  endfor
119 
120  np = floor(np / 2) * 2 // ignore odd cursor
121  redimension /n=(np) positions
122  sort positions, positions
123  // shift upper positions by one so that the rightmost pixel becomes 1.0
124  positions = p >= np / 2 ? positions + 1 : positions
125  positions = positions / dimsize(image, 0)
126 
127  // map innermost cursor pair to peak center and size
128  variable ip2 = np / 2
129  variable ip1 = ip2 - 1
130  variable Cpos = (positions[ip1] + positions[ip2]) / 2
131  variable Csize = positions[ip2] - positions[ip1]
132  if (ip1 >= 0)
133  Cpos = (positions[ip1] + positions[ip2]) / 2
134  Csize = positions[ip2] - positions[ip1]
135  else
136  // default: a small region in the center
137  Cpos = 0.5
138  Csize = 0.2
139  endif
140 
141  // background region
142  ip1 -= 1
143  ip2 += 1
144  variable Lsize
145  variable Hsize
146  if (ip1 >= 0)
147  Lsize = positions[ip1]
148  Hsize = 1 - positions[ip2]
149  else
150  // default: everything outside the peak region
151  Lsize = Cpos - Csize / 2
152  Hsize = 1 - (Cpos + Csize / 2)
153  endif
154 
155  // crop region
156  ip1 -= 1
157  ip2 += 1
158  variable Lcrop
159  variable Hcrop
160  if (ip1 >= 0)
161  Lcrop = positions[ip1]
162  Hcrop = 1 - positions[ip2]
163  else
164  // default: dead corners of the EW4000 at PEARL
165  Lcrop = 0.11
166  Hcrop = 0.11
167  endif
168  Lsize = max(Lsize - Lcrop, 0)
169  Hsize = max(Hsize - Hcrop, 0)
170 
171  string param = ""
172  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
173  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
174  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
175  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
176  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
177  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
178 
179  return param
180 end
181 
214 threadsafe function /wave int_linbg_reduction(source, param)
215  wave source
216  string &param
217 
218  variable nx = dimsize(source, 0)
219  variable ny = dimsize(source, 1)
220 
221  // read parameters
222  variable lcrop = NumberByKey("Lcrop", param, "=", ";")
223  variable lsize = NumberByKey("Lsize", param, "=", ";")
224  variable hcrop = NumberByKey("Hcrop", param, "=", ";")
225  variable hsize = NumberByKey("Hsize", param, "=", ";")
226  variable cpos = NumberByKey("Cpos", param, "=", ";")
227  variable csize = NumberByKey("Csize", param, "=", ";")
228 
229  make /wave /free /n=2 result_waves
230  make /free /n=0 dest1, dest2
231  result_waves[0] = dest1
232  result_waves[1] = dest2
233  adh5_setup_profile(source, dest1, 1)
234  adh5_setup_profile(source, dest2, 1)
235 
236  // validate parameters
237  // background parameters are optional, center parameter is required.
238  if (numtype(lcrop) != 0)
239  lcrop = 0
240  endif
241  if (numtype(lsize) != 0)
242  lsize = 0
243  endif
244  if (numtype(hcrop) != 0)
245  hcrop = 0
246  endif
247  if (numtype(hsize) != 0)
248  hsize = 0
249  endif
250  if (numtype(Cpos) != 0)
251  redimension /n=0 result_waves
252  return result_waves // Cpos parameter missing
253  endif
254  if (numtype(Csize) != 0)
255  redimension /n=0 result_waves
256  return result_waves // Csize parameter missing
257  endif
258 
259  variable lpos = lcrop + lsize / 2
260  variable hpos = 1 - (hcrop + hsize / 2)
261 
262  variable p0
263  variable p1
264 
265  duplicate /free dest1, lbg, hbg
266  if (lsize > 0)
267  p0 = round(lcrop * nx)
268  p1 = round((lcrop + lsize) * nx)
269  ad_profile_y_w(source, p0, p1, lbg)
270  else
271  lbg = 0
272  endif
273  if (hsize > 0)
274  p0 = round((1 - hcrop - hsize) * nx)
275  p1 = round((1 - hcrop) * nx)
276  ad_profile_y_w(source, p0, p1, hbg)
277  else
278  hbg = 0
279  endif
280  if (csize > 0)
281  p0 = round((cpos - csize/2) * nx)
282  p1 = round((cpos + csize/2) * nx)
283  ad_profile_y_w(source, p0, p1, dest1)
284  else
285  dest1 = 0
286  endif
287 
288  variable scale = (cpos - lpos) / (hpos - lpos)
289  dest2 = dest1
290  dest1 -= scale * (hbg - lbg) + lbg
291  dest2 = sqrt(dest2 + scale^2 * (hbg + lbg))
292 
293  string s_note1
294  string s_note2
295  sprintf s_note1, "AxisLabelD=peak integral"
296  sprintf s_note2, "KineticEnergy=%.3f", cpos * nx * dimdelta(source, 0) + dimoffset(source, 0)
297  Note dest1, s_note1
298  Note dest1, s_note2
299  Note dest2, s_note1
300  Note dest2, s_note2
301 
302  return result_waves
303 end
304 
305 function prompt_int_quadbg_reduction(param)
306  string &param
307 
308  variable Lcrop = NumberByKey("Lcrop", param, "=", ";")
309  variable Lsize = NumberByKey("Lsize", param, "=", ";")
310  variable Hcrop = NumberByKey("Hcrop", param, "=", ";")
311  variable Hsize = NumberByKey("Hsize", param, "=", ";")
312  variable Cpos = NumberByKey("Cpos", param, "=", ";")
313  variable Csize = NumberByKey("Csize", param, "=", ";")
314 
315  prompt Lcrop, "Lower cropping region"
316  prompt Hcrop, "Upper cropping region"
317  prompt Lsize, "Lower background region"
318  prompt Hsize, "Upper background region"
319  prompt Cpos, "Center position"
320  prompt Csize, "Center integration region"
321 
322  doprompt "int_quadbg_reduction Parameters", lcrop, hcrop, lsize, hsize, cpos, csize
323  if (v_flag == 0)
324  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
325  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
326  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
327  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
328  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
329  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
330  endif
331 
332  return v_flag
333 end
334 
367 threadsafe function /wave int_quadbg_reduction(source, param)
368  wave source
369  string &param
370 
371  variable nx = dimsize(source, 0)
372  variable ny = dimsize(source, 1)
373 
374  // read parameters
375  variable lcrop = NumberByKey("Lcrop", param, "=", ";")
376  variable lsize = NumberByKey("Lsize", param, "=", ";")
377  variable hcrop = NumberByKey("Hcrop", param, "=", ";")
378  variable hsize = NumberByKey("Hsize", param, "=", ";")
379  variable cpos = NumberByKey("Cpos", param, "=", ";")
380  variable csize = NumberByKey("Csize", param, "=", ";")
381 
382  make /wave /free /n=2 result_waves
383  make /free /n=0 dest1, dest2
384  result_waves[0] = dest1
385  result_waves[1] = dest2
386  adh5_setup_profile(source, dest1, 1)
387  adh5_setup_profile(source, dest2, 1)
388 
389  // validate parameters
390  // background parameters are optional, center parameter is required.
391  if (numtype(lcrop) != 0)
392  lcrop = 0
393  endif
394  if (numtype(lsize) != 0)
395  lsize = 0
396  endif
397  if (numtype(hcrop) != 0)
398  hcrop = 0
399  endif
400  if (numtype(hsize) != 0)
401  hsize = 0
402  endif
403  if (numtype(Cpos) != 0)
404  redimension /n=0 result_waves
405  return result_waves // Cpos parameter missing
406  endif
407  if (numtype(Csize) != 0)
408  redimension /n=0 result_waves
409  return result_waves // Csize parameter missing
410  endif
411 
412  // crop boundaries
413  variable pcl = round(lcrop * nx)
414  variable pch = round((1 - hcrop) * nx)
415  // fit boundaries
416  variable pfl = round((lcrop + lsize) * nx)
417  variable pfh = round((1 - hcrop - hsize) * nx)
418  // integration boundaries
419  variable pil = round((cpos - csize/2) * nx)
420  variable pih = round((cpos + csize/2) * nx)
421 
422  // prepare intermediate data buffer
423  make /n=(nx) /d /free profile, mask, fit
424  setscale /p x dimoffset(source,0), dimdelta(source,0), waveunits(source,0), profile, mask, fit
425  mask = ((p >= pcl) && (p < pfl)) || ((p >= pfh) && (p < pch))
426 
427  variable qq
428  variable sp, sf
429  variable xil = x2pnt(profile, pil)
430  variable xih = x2pnt(profile, pih)
431 
432  make /n=3 /free /d w_coef
433  for (qq = 0; qq < ny; qq += 1)
434  profile = source[p][qq]
435  curvefit /Q /NTHR=1 /W=2 poly 3, kwCWave=w_coef, profile /M=mask
436  fit = poly(w_coef, x)
437  sp = sum(profile, xil, xih)
438  sf = sum(fit, xil, xih)
439  dest1[qq] = sp - sf
440  dest2[qq] = sqrt(sp)
441  endfor
442 
443  string s_note1
444  string s_note2
445  sprintf s_note1, "AxisLabelD=peak integral"
446  sprintf s_note2, "KineticEnergy=%.3f", cpos * nx * dimdelta(source, 0) + dimoffset(source, 0)
447  Note dest1, s_note1
448  Note dest1, s_note2
449  Note dest2, s_note1
450  Note dest2, s_note2
451 
452  return result_waves
453 end
454 
463 function prompt_redim_linbg_reduction(param)
464  string &param
465 
466  variable Lcrop = NumberByKey("Lcrop", param, "=", ";")
467  variable Lsize = NumberByKey("Lsize", param, "=", ";")
468  variable Hcrop = NumberByKey("Hcrop", param, "=", ";")
469  variable Hsize = NumberByKey("Hsize", param, "=", ";")
470  variable Cpos = NumberByKey("Cpos", param, "=", ";")
471  variable Csize = NumberByKey("Csize", param, "=", ";")
472 
473  prompt Lcrop, "Lower cropping region"
474  prompt Hcrop, "Upper cropping region"
475  prompt Lsize, "Lower background region"
476  prompt Hsize, "Upper background region"
477  prompt Cpos, "Center position"
478  prompt Csize, "Center integration region"
479 
480  doprompt "redim_linbg_reduction Parameters", lcrop, hcrop, lsize, hsize, cpos, csize
481  if (v_flag == 0)
482  param = ReplaceNumberByKey("Lcrop", param, Lcrop, "=", ";")
483  param = ReplaceNumberByKey("Lsize", param, Lsize, "=", ";")
484  param = ReplaceNumberByKey("Hcrop", param, Hcrop, "=", ";")
485  param = ReplaceNumberByKey("Hsize", param, Hsize, "=", ";")
486  param = ReplaceNumberByKey("Cpos", param, Cpos, "=", ";")
487  param = ReplaceNumberByKey("Csize", param, Csize, "=", ";")
488  endif
489 
490  return v_flag
491 end
492 
526 threadsafe function /wave redim_linbg_reduction(source, param)
527  wave source
528  string &param
529 
530  variable nx = dimsize(source, 0)
531  variable ny = dimsize(source, 1)
532 
533  duplicate /free source, source_redim
534  redimension /n=(nx * ny) source_redim
535  nx += 1
536  redimension /n=(nx, ny) source_redim
537 
538  return int_linbg_reduction(source_redim, param)
539 end
540 
546 function test_gauss4_reduction(image)
547  wave image
548 
549  string param = ""
550 
551  param = ReplaceNumberByKey("rngl", param, -inf, "=", ";")
552  param = ReplaceNumberByKey("rngh", param, inf, "=", ";")
553  param = ReplaceNumberByKey("npeaks", param, 4, "=", ";")
554  param = ReplaceNumberByKey("ybox", param, 1, "=", ";")
555  param = ReplaceNumberByKey("pos1", param, 11, "=", ";")
556  param = ReplaceNumberByKey("wid1", param, 0.1, "=", ";")
557  param = ReplaceNumberByKey("pos2", param, 12, "=", ";")
558  param = ReplaceNumberByKey("wid2", param, 0.2, "=", ";")
559  param = ReplaceNumberByKey("pos3", param, 13, "=", ";")
560  param = ReplaceNumberByKey("wid3", param, 0.3, "=", ";")
561  param = ReplaceNumberByKey("pos4", param, 14, "=", ";")
562  param = ReplaceNumberByKey("wid4", param, 0.4, "=", ";")
563 
564  wave /wave results = gauss4_reduction(image, param)
565 
566  variable npk = numpnts(results) / 2
567  variable ipk
568  string sw
569  for (ipk = 0; ipk < npk; ipk += 1)
570  sw = "test_int_" + num2str(ipk + 1)
571  duplicate /o results[ipk], $sw
572  sw = "test_sig_" + num2str(ipk + 1)
573  duplicate /o results[ipk + npk], $sw
574  endfor
575 end
576 
580 function prompt_gauss4_reduction(param)
581  string &param
582 
583  variable rngl = NumberByKey("rngl", param, "=", ";")
584  variable rngh = NumberByKey("rngh", param, "=", ";")
585  variable pos1 = NumberByKey("pos1", param, "=", ";")
586  variable wid1 = NumberByKey("wid1", param, "=", ";")
587  variable pos2 = NumberByKey("pos2", param, "=", ";")
588  variable wid2 = NumberByKey("wid2", param, "=", ";")
589  variable pos3 = NumberByKey("pos3", param, "=", ";")
590  variable wid3 = NumberByKey("wid3", param, "=", ";")
591  variable pos4 = NumberByKey("pos4", param, "=", ";")
592  variable wid4 = NumberByKey("wid4", param, "=", ";")
593  variable npeaks = NumberByKey("npeaks", param, "=", ";")
594  variable ybox = NumberByKey("ybox", param, "=", ";")
595 
596  prompt rngl, "range low"
597  prompt rngh, "range high"
598  prompt pos1, "position 1"
599  prompt wid1, "width 1"
600  prompt pos2, "position 2"
601  prompt wid2, "width 2"
602  prompt pos3, "position 3"
603  prompt wid3, "width 3"
604  prompt pos4, "position 4"
605  prompt wid4, "width 4"
606  prompt npeaks, "number of peaks"
607  prompt ybox, "ybox (1 or 3)"
608 
609  doprompt "gauss4_reduction reduction parameters (1/2)", rngl, rngh, npeaks, ybox
610  if (v_flag == 0)
611  param = ReplaceNumberByKey("rngl", param, rngl, "=", ";")
612  param = ReplaceNumberByKey("rngh", param, rngh, "=", ";")
613  param = ReplaceNumberByKey("npeaks", param, npeaks, "=", ";")
614  param = ReplaceNumberByKey("ybox", param, ybox, "=", ";")
615 
616  doprompt "gauss4_reduction reduction parameters (2/2)", pos1, wid1, pos2, wid2, pos3, wid3, pos4, wid4
617  if (v_flag == 0)
618  param = ReplaceNumberByKey("pos1", param, pos1, "=", ";")
619  param = ReplaceNumberByKey("wid1", param, wid1, "=", ";")
620  param = ReplaceNumberByKey("pos2", param, pos2, "=", ";")
621  param = ReplaceNumberByKey("wid2", param, wid2, "=", ";")
622  param = ReplaceNumberByKey("pos3", param, pos3, "=", ";")
623  param = ReplaceNumberByKey("wid3", param, wid3, "=", ";")
624  param = ReplaceNumberByKey("pos4", param, pos4, "=", ";")
625  param = ReplaceNumberByKey("wid4", param, wid4, "=", ";")
626  endif
627  endif
628 
629  return v_flag
630 end
631 
672 threadsafe function /wave gauss4_reduction(source, param)
673  wave source
674  string &param
675 
676  variable nx = dimsize(source, 0)
677  variable ny = dimsize(source, 1)
678 
679  // read parameters
680  variable rngl = NumberByKey("rngl", param, "=", ";")
681  variable rngh = NumberByKey("rngh", param, "=", ";")
682  variable pos1 = NumberByKey("pos1", param, "=", ";")
683  variable wid1 = NumberByKey("wid1", param, "=", ";")
684  variable pos2 = NumberByKey("pos2", param, "=", ";")
685  variable wid2 = NumberByKey("wid2", param, "=", ";")
686  variable pos3 = NumberByKey("pos3", param, "=", ";")
687  variable wid3 = NumberByKey("wid3", param, "=", ";")
688  variable pos4 = NumberByKey("pos4", param, "=", ";")
689  variable wid4 = NumberByKey("wid4", param, "=", ";")
690  variable npeaks = NumberByKey("npeaks", param, "=", ";")
691  variable ybox = NumberByKey("ybox", param, "=", ";")
692 
693  // prepare curve fit
694  variable ipk
695  make /free xprof
696  adh5_setup_profile(source, xprof, 0)
697  duplicate /free xprof, xprof_sig
698  variable pl = max(x2pnt(xprof, rngl), 0)
699  variable ph = min(x2pnt(xprof, rngh), numpnts(xprof) - 1)
700 
701  make /free /n=(npeaks) peak_coef
702  peak_coef = p * 3 + 2
703  variable n_coef = npeaks * 3 + 2
704  make /free /d /n=14 w_coef, W_sigma
705  w_coef[0] = {0, 0, 1, pos1, wid1, 1, pos2, wid2, 1, pos3, wid3, 1, pos4, wid4}
706  redimension /n=(n_coef) w_coef, w_sigma
707 
708  // text constraints cannot be used in threadsafe functions.
709  // the following matrix-vector forumlation is equivalent to:
710  // make /free /T /N=6 constraints
711  // constraints[0] = {"K2 >= 0", "K5 >= 0", "K8 >= 0", "K11 >= 0", "K1 <= 0", "K0 => 0"}
712  make /free /n=(npeaks + 2, numpnts(w_coef)) cmat
713  make /free /n=(npeaks + 2) cvec
714  cmat = 0
715  cmat[0][0] = -1
716  cmat[1][1] = 1
717  cvec = 0
718 
719  string hold = "00"
720  for (ipk=0; ipk < npeaks; ipk += 1)
721  hold += "011"
722  cmat[2 + ipk][2 + ipk*3] = -1
723  endfor
724 
725  // prepare output
726  make /free /n=(npeaks * 2) /wave result_waves
727  string s_note
728  for (ipk = 0; ipk < npeaks; ipk += 1)
729  make /free /n=0 pk_int
730  adh5_setup_profile(source, pk_int, 1)
731  pk_int = nan
732  sprintf s_note, "AxisLabelD=peak %u integral", ipk+1
733  Note pk_int, s_note
734  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * 3]
735  Note pk_int, s_note
736  result_waves[ipk] = pk_int
737 
738  make /free /n=0 pk_sig
739  adh5_setup_profile(source, pk_sig, 1)
740  pk_sig = nan
741  sprintf s_note, "AxisLabelD=peak %u sigma", ipk+1
742  Note pk_sig, s_note
743  sprintf s_note, "KineticEnergy=%.3f", w_coef[3 + ipk * 3]
744  Note pk_sig, s_note
745  result_waves[ipk + npeaks] = pk_sig
746 
747  waveclear pk_int, pk_sig
748  endfor
749 
750  // loop over angle scale
751  variable p0 = 0
752  variable p1 = dimsize(source, 1) - 1
753  variable pp
754  variable wmin
755  variable wmax
756  if (ybox > 1)
757  p0 += ceil((ybox - 1) / 2)
758  p1 -= ceil((ybox - 1) / 2)
759  endif
760  variable V_FitNumIters
761 
762  for (pp = p0; pp <= p1; pp += 1)
763  // box average
764  xprof = source[p][pp]
765  if (ybox > 1)
766  xprof += source[p][pp-1] + source[p][pp+1]
767  endif
768  xprof_sig = max(sqrt(xprof), 1)
769  xprof /= ybox
770  xprof_sig /= ybox
771 
772  // generate guess
773  wmin = wavemin(xprof)
774  wmax = wavemax(xprof)
775  w_coef[0] = wmin
776  w_coef[1] = 0
777 
778  for (ipk=0; ipk < npeaks; ipk += 1)
779  w_coef[2 + ipk*3] = wmax - wmin
780  endfor
781  FuncFit /H=hold /Q /NTHR=1 /N /W=2 MultiGaussLinBG_AO w_coef xprof[pl,ph] /C={cmat, cvec} /I=1 /W=xprof_sig[pl,ph]
782  wave w_sigma
783 
784  // retrieve results, leave them at nan if the fit did not converge
785  if (V_FitNumIters < 40)
786  for (ipk = 0; ipk < npeaks; ipk += 1)
787  wave val = result_waves[ipk]
788  wave sig = result_waves[ipk + npeaks]
789  val[pp] = max(w_coef[peak_coef[ipk]], 0)
790  sig[pp] = max(w_sigma[peak_coef[ipk]], 0)
791  endfor
792  endif
793  endfor
794 
795  // calculate integral
796  for (ipk = 0; ipk < npeaks; ipk += 1)
797  wave val = result_waves[ipk]
798  wave sig = result_waves[ipk + npeaks]
799  val *= w_coef[peak_coef[ipk] + 2] * sqrt(pi)
800  sig *= w_coef[peak_coef[ipk] + 2] * sqrt(pi)
801  endfor
802 
803  return result_waves
804 end
805 
806 
838 function /s find_gauss4_reduction_params(spectrum, peakpos)
839  wave spectrum
840  wave peakpos
841  string param = ""
842 
843  variable wmin = wavemin(spectrum)
844  variable wmax = wavemax(spectrum)
845 
846  // read parameters
847  variable rngl = dimoffset(spectrum, 0)
848  variable rngh = dimoffset(spectrum, 0) + dimdelta(spectrum, 0) * (dimsize(spectrum, 0) - 1)
849  make /n=4 /free positions, widths
850  variable npeaks = numpnts(peakpos)
851  variable ybox = 1
852  positions = 0
853  positions[0, npeaks-1] = peakpos[p]
854  widths = 0.2
855 
856  variable n_coef = npeaks * 3 + 2
857  make /free /d /n=(n_coef) w_coef
858  w_coef = 0
859  w_coef[0] = wmin
860  w_coef[1] = 0
861 
862  make /free /n=(2+npeaks, numpnts(w_coef)) cmat
863  make /free /n=(2+npeaks) cvec
864  cmat = 0
865  cmat[0][0] = -1
866  cmat[1][1] = 1
867  cvec = 0
868 
869  variable ip
870  for (ip=0; ip < npeaks; ip += 1)
871  cmat[2 + ip][2 + ip*3] = -1
872  w_coef[2 + ip*3] = wmax - wmin
873  w_coef[3 + ip*3] = peakpos[ip]
874  w_coef[4 + ip*3] = widths[ip]
875  endfor
876 
877  variable V_FitNumIters
878  FuncFit /Q /NTHR=1 /N MultiGaussLinBG w_coef spectrum /C={cmat, cvec}
879 
880  for (ip=0; ip < npeaks; ip += 1)
881  positions[ip] = w_coef[3 + ip * 3]
882  widths[ip ] = abs(w_coef[4 + ip * 3])
883  endfor
884  for (ip=npeaks; ip < 4; ip += 1)
885  positions[ip] = 0
886  widths[ip] = 0.2
887  endfor
888 
889  param = ReplaceNumberByKey("rngl", param, rngl, "=", ";")
890  param = ReplaceNumberByKey("rngh", param, rngh, "=", ";")
891  param = ReplaceNumberByKey("npeaks", param, npeaks, "=", ";")
892  param = ReplaceNumberByKey("ybox", param, ybox, "=", ";")
893  param = ReplaceNumberByKey("pos1", param, positions[0], "=", ";")
894  param = ReplaceNumberByKey("wid1", param, widths[0], "=", ";")
895  param = ReplaceNumberByKey("pos2", param, positions[1], "=", ";")
896  param = ReplaceNumberByKey("wid2", param, widths[1], "=", ";")
897  param = ReplaceNumberByKey("pos3", param, positions[2], "=", ";")
898  param = ReplaceNumberByKey("wid3", param, widths[2], "=", ";")
899  param = ReplaceNumberByKey("pos4", param, positions[3], "=", ";")
900  param = ReplaceNumberByKey("wid4", param, widths[3], "=", ";")
901 
902  return param
903 end
904 
912 function test_shockley_anglefit(image, branch)
913  wave image
914  variable branch
915 
916  string param = ""
917  param = ReplaceStringByKey("branch", param, num2str(branch), "=", ";")
918 
919  string s_branch
920  if (branch >= 0)
921  s_branch = "p"
922  else
923  s_branch = "n"
924  endif
925  string pkpos_name = "saf_pkpos_" + s_branch
926  string pkwid_name = "saf_pkwid_" + s_branch
927 
928  wave /wave results = shockley_anglefit(image, param)
929  duplicate results[0], $pkpos_name
930  duplicate results[1], $pkwid_name
931 end
932 
933 function prompt_Shockley_anglefit(param)
934  string &param
935 
936  variable branch = NumberByKey("branch", param, "=", ";")
937 
938  prompt branch, "Branch (-1 or +1)"
939 
940  doprompt "Shockley_anglefit_reduction Parameters", branch
941  if (v_flag == 0)
942  param = ReplaceNumberByKey("branch", param, branch, "=", ";")
943  endif
944 
945  return v_flag
946 end
947 
970 threadsafe function /wave Shockley_anglefit(source, param)
971  wave source
972  string &param
973 
974  variable nx = dimsize(source, 0)
975  variable ny = dimsize(source, 1)
976 
977  // read parameters
978  variable branch = NumberByKey("branch", param, "=", ";")
979 
980  // validate parameters
981  if (numtype(branch) != 0)
982  branch = +1
983  endif
984 
985  // prepare output
986  make /wave /free /n=2 result_waves
987  make /free /n=0 dest1, dest2
988  result_waves[0] = dest1
989  result_waves[1] = dest2
990  adh5_setup_profile(source, dest1, 0)
991  adh5_setup_profile(source, dest2, 0)
992  dest1 = nan
993  dest2 = nan
994 
995  // select angle range
996  // hard-coded for a particular measurement series
997  variable y0
998  variable y1
999  if (branch < 0)
1000  y0 = -5
1001  y1 = 0
1002  else
1003  y0 = 0
1004  y1 = 5
1005  endif
1006 
1007  // select energy range
1008  // start at the point of highest intensity and go up 0.45 eV
1009  variable p0
1010  variable p1
1011  variable q0
1012  variable q1
1013  duplicate /free dest1, center
1014  q0 = round((y0 - dimoffset(source, 1)) / dimdelta(source, 1))
1015  q1 = round((y1 - dimoffset(source, 1)) / dimdelta(source, 1))
1016  ad_profile_x_w(source, q0, q1, center)
1017  wavestats /q/m=1 center
1018  p0 = round((v_maxloc - dimoffset(source, 0)) / dimdelta(source, 0))
1019  p1 = round((v_maxloc + 0.4 - dimoffset(source, 0)) / dimdelta(source, 0))
1020 
1021  // prepare intermediate data buffer
1022  make /n=(ny)/d/free profile
1023  setscale /p x dimoffset(source,1), dimdelta(source,1), waveunits(source,1), profile
1024 
1025  variable pp
1026  for (pp = p0; pp <= p1; pp += 1)
1027  profile = source[pp][p]
1028  curvefit /Q /NTHR=1 /W=2 gauss profile(y0,y1)
1029  wave w_coef
1030  dest1[pp] = w_coef[2]
1031  dest2[pp] = w_coef[3]
1032  endfor
1033 
1034  return result_waves
1035 end
1036 
1037 function scienta_norm(w, x): fitfunc
1038  wave w
1039  variable x
1040 
1041  return w[0] * (x^2 - w[1]^2)
1042 end
1043 
1044 function /wave fit_scienta_ang_transm(data, params)
1045  wave data // measured angular distribution (1D)
1046  wave /z params
1047 
1048  if (!waveexists(params))
1049  make /n=12 /o params
1050  endif
1051  redimension /n=12/d params
1052 
1053  variable h = wavemax(data) - wavemin(data)
1054  params[0] = h / 2
1055  params[1] = 0
1056  params[2] = 7
1057  params[3] = h / 4
1058  params[4] = -23
1059  params[5] = 4
1060  params[6] = h / 4
1061  params[7] = +23
1062  params[8] = 4
1063  params[9] = h / 2
1064  params[10] = 0
1065  params[11] = -0.001
1066  FuncFit /NTHR=0 /q scienta_ang_transm params data
1067 
1068  return params
1069 end
1070 
1071 threadsafe function scienta_ang_transm(w, x): fitfunc
1072  // parameterized angular transmission function of the analyser
1073  wave w // coefficients
1074  // w[0] = amplitude gauss 1
1075  // w[1] = position gauss 1
1076  // w[2] = width gauss 1
1077  // w[3] = amplitude gauss 2
1078  // w[4] = position gauss 2
1079  // w[5] = width gauss 2
1080  // w[6] = amplitude gauss 3
1081  // w[7] = position gauss 3
1082  // w[8] = width gauss 3
1083  // w[9] = constant background
1084  // w[10] = linear background
1085  // w[11] = quadratic background
1086  variable x
1087 
1088  make /free /n=4 /d w_int
1089  w_int[0] = 0
1090  w_int[1,] = w[p - 1]
1091  variable pk1 = gauss1d(w_int, x)
1092  w_int[1,] = w[p + 2]
1093  variable pk2 = gauss1d(w_int, x)
1094  w_int[1,] = w[p + 5]
1095  variable pk3 = gauss1d(w_int, x)
1096  w_int[0,2] = w[9 + p]
1097  w_int[3] = 0
1098  variable bg = poly(w_int, x)
1099 
1100  return bg + pk1 + pk2 + pk3
1101 end
1102 
1103 function /wave fit_scienta_poly_bg(data, params, bgterms)
1104  wave data // measured distribution (2D)
1105  wave /z params // wave, will be redimensioned for the correct size
1106  variable bgterms // number of terms in the polynomial background: 2, 3, or 4
1107 
1108  if (!waveexists(params))
1109  make /n=15 /o params
1110  endif
1111  redimension /n=15 /d params
1112 
1113  variable wmax = wavemax(data)
1114  variable wmin = wavemin(data)
1115  params[0] = 0
1116  params[1] = 7
1117  params[2] = 1 / 2
1118  params[3] = -23
1119  params[4] = 4
1120  params[5] = 1 / 2
1121  params[6] = +23
1122  params[7] = 4
1123  params[8] = 1
1124  params[9] = 0
1125  params[10] = -0.001
1126  params[11] = wmin
1127  params[12] = (wmax - wmin) / dimdelta(data,1) / dimsize(data,1)
1128  params[13] = 0
1129  params[14] = 0
1130 
1131  string h = "0000000000000"
1132  if (bgterms < 3)
1133  h = h + "1"
1134  else
1135  h = h + "0"
1136  endif
1137  if (bgterms < 4)
1138  h = h + "1"
1139  else
1140  h = h + "0"
1141  endif
1142  FuncFitMD /NTHR=1 /q /h=h scienta_poly_bg params data
1143 
1144  return params
1145 end
1146 
1147 function scienta_poly_bg(w, e, a): fitfunc
1148  // polynomial background with
1149  // parameterized angular transmission function of the analyser
1150  wave w // coefficients
1151  // angular transmission, varies with a
1152  // amplitude of gauss 1 = 1 constant
1153  // other peak amplitudes and linear terms are relative to gauss 1
1154  // w[0] = position gauss 1
1155  // w[1] = width gauss 1
1156  // w[2] = amplitude gauss 2, relative to gauss 1
1157  // w[3] = position gauss 2
1158  // w[4] = width gauss 2
1159  // w[5] = amplitude gauss 3, relative to gauss 1
1160  // w[6] = position gauss 3
1161  // w[7] = width gauss 3
1162  // w[8] = constant term
1163  // w[9] = linear term
1164  // w[10] = quadratic term
1165  // spectral background, varies with e
1166  // w[11] = constant term
1167  // w[12] = linear term
1168  // w[13] = quadratic term
1169  // w[14] = cubic term
1170  variable a // detection angle
1171  variable e // electron energy
1172 
1173  make /free /n=4 /d w_int
1174  variable p0 = 0
1175 
1176  w_int[0] = 0
1177  w_int[1] = 1
1178  w_int[2,] = w[p0 + p - 2]
1179  variable pk1 = gauss1d(w_int, a)
1180  p0 += 2
1181 
1182  w_int[1,] = w[p0 + p - 1]
1183  variable pk2 = gauss1d(w_int, a)
1184  p0 += 3
1185 
1186  w_int[1,] = w[p0 + p - 1]
1187  variable pk3 = gauss1d(w_int, a)
1188  p0 += 3
1189 
1190  w_int[0,2] = w[p0 + p]
1191  w_int[3] = 0
1192  variable base = poly(w_int, a)
1193  p0 += 3
1194 
1195  w_int[0,3] = w[p0 + p]
1196  variable bg = poly(w_int, e)
1197 
1198  return bg * (base + pk1 + pk2 + pk3)
1199 end
threadsafe variable MultiGaussLinBG(wave w, variable x)
multiple gaussian peaks on a linear background fit function.
+
threadsafe variable MultiGaussLinBG_AO(wave pw, wave yw, wave xw)
multiple gaussian peaks on a linear background fit function (all at once).
+
variable prompt_gauss4_reduction(string *param)
prompt for the gauss4_reduction parameters
+
threadsafe wave redim_linbg_reduction(wave source, string *param)
linear background reduction function for incorrectly dimensioned scienta image
+
variable test_gauss4_reduction(wave image)
apply the gauss4_reduction function to a single image
+
threadsafe wave ad_profile_x_w(wave dataset, variable q1, variable q2, wave destwave, variable noavg=defaultValue)
1D cut through 2D dataset along X dimension, existing destination wave.
+
threadsafe variable adh5_setup_profile(wave image, wave profile, variable dim)
set up a one-dimensional wave for a line profile based on a 2D original wave.
+
variable prompt_int_quadbg_reduction(string *param)
+
threadsafe wave int_linbg_reduction(wave source, string *param)
linear-background subtracted integration reduction function.
+
threadsafe wave gauss4_reduction(wave source, string *param)
fit horizontal cuts of an image with up to four gaussian peaks on a linear background ...
+
variable prompt_redim_linbg_reduction(string *param)
parameter dialog for the redim_linbg_reduction() function
+
threadsafe wave ad_profile_y_w(wave dataset, variable p1, variable p2, wave destwave, variable noavg=defaultValue)
1D cut through 2D dataset along X dimension, existing destination wave.
+
threadsafe wave int_quadbg_reduction(wave source, string *param)
integrate peak area minus a quadratic background
+
variable prompt_int_linbg_reduction(string *param)
prompt the user for integrate on linear background reduction parameters.
+
string csr_int_linbg_reduction(string win)
set reduction parameters from cursors in a graph.
+
string capture_int_linbg_cursors()
this function is for testing only, until we implement a proper interface
+
+
+Functions
pearl-tools.ipf File Reference
- +
#include "pearl-gui-tools"
+

Go to the source code of this file.

+ + + + + + + + + + + + + + +

+Functions

variable DefaultWaveIterator (wave w, string *sdata)
 
variable AppendToGraphIterator (wave w, string *sdata)
 
variable SumWavesIterator (wave w, string *sdata)
 
string IterateWaves (string matchStr, funcref iterator, string sdata)
 
variable DefaultFolderIterator (dfref df, string *sdata)
 
string IterateDataFolders (string matchStr, funcref iterator, string sdata, string progress_title=defaultValue)
 
+

Function Documentation

+ +

◆ AppendToGraphIterator()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable AppendToGraphIterator (wave w,
string * sdata 
)
+
+ +

Definition at line 26 of file pearl-tools.ipf.

+ +
+
+ +

◆ DefaultFolderIterator()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable DefaultFolderIterator (dfref df,
string * sdata 
)
+
+ +

Definition at line 65 of file pearl-tools.ipf.

+ +
+
+ +

◆ DefaultWaveIterator()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable DefaultWaveIterator (wave w,
string * sdata 
)
+
+ +

Definition at line 18 of file pearl-tools.ipf.

+ +
+
+ +

◆ IterateDataFolders()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
string IterateDataFolders (string matchStr,
funcref iterator,
string sdata,
string progress_title = defaultValue 
)
+
+ +

Definition at line 79 of file pearl-tools.ipf.

+ +
+
+ +

◆ IterateWaves()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
string IterateWaves (string matchStr,
funcref iterator,
string sdata 
)
+
+ +

Definition at line 45 of file pearl-tools.ipf.

+ +
+
+ +

◆ SumWavesIterator()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable SumWavesIterator (wave w,
string * sdata 
)
+
+ +

Definition at line 34 of file pearl-tools.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #pragma version = 1.00
3 #pragma IgorVersion = 6.2
4 #pragma ModuleName = PearlTools
5 #include "pearl-gui-tools"
6 
7 // general programming tools for Igor
8 
9 // $Id$
10 // author: matthias.muntwiler@psi.ch
11 // Copyright (c) 2009-14 Paul Scherrer Institut
12 
13 // Licensed under the Apache License, Version 2.0 (the "License");
14 // you may not use this file except in compliance with the License.
15 // You may obtain a copy of the License at
16 // http://www.apache.org/licenses/LICENSE-2.0
17 
18 function DefaultWaveIterator(w, sdata)
19 // function prototype for IterateWaves
20  wave w // wave which the iterator is supposed to work on
21  string &sdata // string with additional data, shared between calls
22  // this is a pass-by-reference argument,
23  // the function may modify the string
24 end
25 
26 function AppendToGraphIterator(w, sdata)
27 // append iterated waves to the current graph
28  wave w // wave to be displayed
29  string &sdata // not used
30 
31  appendtograph w
32 end
33 
34 function SumWavesIterator(w, sdata)
35 // sum waves into one result wave
36  wave w // wave which the iterator is supposed to work on
37  string &sdata // name of the result wave, can include absolute path
38  // the wave must exist and compatible with the summands
39  // the caller is responsible for initialization of the wave
40 
41  wave result = $sdata
42  result += w
43 end
44 
45 function/s IterateWaves(matchStr, iterator, sdata)
46 // iterate over all waves matching a specified pattern (see built-in WaveList function),
47 // passing each wave to a user-defined iterator function
48  string matchStr // matchStr as for WaveList
49  funcref DefaultWaveIterator iterator // iterator function
50  // use the DefaultWaveIterator function as a template
51  string sdata // data string passed to iterator function
52  // the iterator may modify the string
53  // the function returns the string at the end
54 
55  string wlist = WaveList(matchStr, ";", "")
56  variable n = ItemsInList(wlist, ";")
57  variable i
58  for (i = 0; i < n; i += 1)
59  wave w = $(StringFromList(i, wlist, ";"))
60  iterator(w, sdata)
61  endfor
62  return sdata
63 end
64 
65 function DefaultFolderIterator(df, sdata)
66 // function prototype for IterateWaves
67  dfref df // data folder reference which the iterator is supposed to work on
68  string &sdata // string with additional data, shared between calls
69  // this is a pass-by-reference argument,
70  // the function may modify the string
71 
72  // switch to requested data folder
73  setdatafolder df
74  // for testing
75  print getdatafolder(1)
76  // no need to switch back to original folder
77 end
78 
79 function/s IterateDataFolders(matchStr, iterator, sdata, [progress_title])
80 // iterate over all data folders matching a specified pattern in the current data folder,
81 // passing each folder to a user-defined iterator function
82  string matchStr // matchStr as for the built-in stringmatch function
83  funcref DefaultFolderIterator iterator // iterator function
84  // use the DefaultFolderIterator function as a template
85  string sdata // data string passed to iterator function
86  // the iterator may modify the string
87  // the function returns the string at the end
88  string progress_title // title of the progress window (optional)
89  // if not specified or empty, the progress window will not be shown.
90  // if the progress window is show, the user can abort the iteration.
91  // the function result does not indicate whether the iteration was completed or aborted.
92  // the iterator and caller must take care of leaving the data in a consistent state.
93 
94  if (ParamIsDefault(progress_title))
95  progress_title = ""
96  endif
97  variable show_progress = strlen(progress_title) > 0
98 
99  dfref origdf = GetDataFolderDFR()
100  dfref curdf
101  variable index = 0
102  variable abort_req = 0
103  string objName
104 
105  variable ndf = CountObjectsDFR(origdf, 4)
106  if (show_progress)
107  display_progress_panel(progress_title, "", ndf)
108  endif
109 
110  do
111  objName = GetIndexedObjNameDFR(origdf, 4, index)
112  if (strlen(objName) == 0)
113  break
114  endif
115  if (stringmatch(objname, matchstr))
116  if (show_progress)
117  abort_req = update_progress_panel(index, message=objName)
118  if (abort_req)
119  break
120  endif
121  endif
122  setdatafolder origdf
123  curdf = $(":" + objname)
124  iterator(curdf, sdata)
125  endif
126  index += 1
127  while(1)
128 
129  if (show_progress)
130  kill_progress_panel()
131  endif
132 
133  setdatafolder origdf
134  return sdata
135 end
variable kill_progress_panel()
+
string IterateDataFolders(string matchStr, funcref iterator, string sdata, string progress_title=defaultValue)
Definition: pearl-tools.ipf:79
+
variable display_progress_panel(string title, string message, variable progress_max)
+
variable AppendToGraphIterator(wave w, string *sdata)
Definition: pearl-tools.ipf:26
+
string IterateWaves(string matchStr, funcref iterator, string sdata)
Definition: pearl-tools.ipf:45
+
variable DefaultWaveIterator(wave w, string *sdata)
Definition: pearl-tools.ipf:18
+
variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
+
variable SumWavesIterator(wave w, string *sdata)
Definition: pearl-tools.ipf:34
+
variable DefaultFolderIterator(dfref df, string *sdata)
Definition: pearl-tools.ipf:65
+
+
+Functions
pearl-vector-operations.ipf File Reference

Go to the source code of this file.

+ + + + + + + + + + + + + + + + + + + + +

+Functions

variable rotate2d_x (variable xx, variable yy, variable angle)
 
variable rotate2d_y (variable xx, variable yy, variable angle)
 
wave create_rotation_matrix_free ()
 
wave set_rotation_x (wave matrix, variable angle)
 
wave set_rotation_y (wave matrix, variable angle)
 
wave set_rotation_z (wave matrix, variable angle)
 
variable rotate_x_wave (wave inout, variable angle)
 
variable rotate_y_wave (wave inout, variable angle)
 
variable rotate_z_wave (wave inout, variable angle)
 
+

Function Documentation

+ +

◆ create_rotation_matrix_free()

+ +
+
+ + + + + + + +
wave create_rotation_matrix_free ()
+
+ +

Definition at line 26 of file pearl-vector-operations.ipf.

+ +
+
+ +

◆ rotate2d_x()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
variable rotate2d_x (variable xx,
variable yy,
variable angle 
)
+
+ +

Definition at line 10 of file pearl-vector-operations.ipf.

+ +
+
+ +

◆ rotate2d_y()

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
variable rotate2d_y (variable xx,
variable yy,
variable angle 
)
+
+ +

Definition at line 18 of file pearl-vector-operations.ipf.

+ +
+
+ +

◆ rotate_x_wave()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable rotate_x_wave (wave inout,
variable angle 
)
+
+ +

Definition at line 83 of file pearl-vector-operations.ipf.

+ +
+
+ +

◆ rotate_y_wave()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable rotate_y_wave (wave inout,
variable angle 
)
+
+ +

Definition at line 101 of file pearl-vector-operations.ipf.

+ +
+
+ +

◆ rotate_z_wave()

+ +
+
+ + + + + + + + + + + + + + + + + + +
variable rotate_z_wave (wave inout,
variable angle 
)
+
+ +

Definition at line 119 of file pearl-vector-operations.ipf.

+ +
+
+ +

◆ set_rotation_x()

+ +
+
+ + + + + + + + + + + + + + + + + + +
wave set_rotation_x (wave matrix,
variable angle 
)
+
+ +

Definition at line 35 of file pearl-vector-operations.ipf.

+ +
+
+ +

◆ set_rotation_y()

+ +
+
+ + + + + + + + + + + + + + + + + + +
wave set_rotation_y (wave matrix,
variable angle 
)
+
+ +

Definition at line 51 of file pearl-vector-operations.ipf.

+ +
+
+ +

◆ set_rotation_z()

+ +
+
+ + + + + + + + + + + + + + + + + + +
wave set_rotation_z (wave matrix,
variable angle 
)
+
+ +

Definition at line 67 of file pearl-vector-operations.ipf.

+ +
+
-Go to the documentation of this file.
+Go to the documentation of this file.
1 #pragma rtGlobals=3
2 #pragma version = 2.0
3 #pragma IgorVersion = 6.1
4 #pragma ModuleName = PearlVectorOperations
5 
6 // author: matthias.muntwiler@psi.ch
7 // Copyright (c) 2011-13 Paul Scherrer Institut
8 // $Id$
9 
10 function rotate2d_x(xx, yy, angle)
11  // rotates a 2D cartesian vector and returns its x component
12  variable xx, yy
13  variable angle // rotation angle in degrees
14 
15  return xx * cos(angle * pi / 180) - yy * sin(angle * pi / 180)
16 end
17 
18 function rotate2d_y(xx, yy, angle)
19  // rotates a 2D cartesian vector and returns its y component
20  variable xx, yy
21  variable angle // rotation angle in degrees
22 
23  return xx * sin(angle * pi / 180) + yy * cos(angle * pi / 180)
24 end
25 
26 function /wave create_rotation_matrix_free()
27  // creates a matrix which represents a 3-vector rotation
28  // the matrix is initialized as identity
29 
30  make /n=(3,3)/free matrix
31  matrix = p == q // identity
32  return matrix
33 end
34 
35 function /wave set_rotation_x(matrix, angle)
36  // calculates a matrix representing a 3-vector rotation around the x axis
37  wave matrix // rotation matrix
38  variable angle // rotation angle in degrees
39 
40  variable si = sin(angle * pi / 180)
41  variable co = cos(angle * pi / 180)
42 
43  matrix[1][1] = co
44  matrix[2][2] = co
45  matrix[2][1] = si
46  matrix[1][2] = -si
47 
48  return matrix
49 end
50 
51 function /wave set_rotation_y(matrix, angle)
52  // calculates a matrix representing a 3-vector rotation around the y axis
53  wave matrix // rotation matrix
54  variable angle // rotation angle in degrees
55 
56  variable si = sin(angle * pi / 180)
57  variable co = cos(angle * pi / 180)
58 
59  matrix[0][0] = co
60  matrix[2][2] = co
61  matrix[0][2] = si
62  matrix[2][0] = -si
63 
64  return matrix
65 end
66 
67 function /wave set_rotation_z(matrix, angle)
68  // calculates a matrix representing a 3-vector rotation around the z axis
69  wave matrix // rotation matrix
70  variable angle // rotation angle in degrees
71 
72  variable si = sin(angle * pi / 180)
73  variable co = cos(angle * pi / 180)
74 
75  matrix[0][0] = co
76  matrix[1][1] = co
77  matrix[1][0] = si
78  matrix[0][1] = -si
79 
80  return matrix
81 end
82 
83 function rotate_x_wave(inout, angle)
84  // rotates a wave of 3-vectors about the x axis
85  wave inout // wave with dimensions (3, N), N >= 1, (x, y, z)
86  // result will be in same wave
87  variable angle // rotation angle in degrees
88 
89  wave m_rotation_x = create_rotation_matrix_free()
90  make /n=3/d/free w_temp_rotate_x
91  variable ivec, nvec
92  nvec = max(DimSize(inout, 1), 1)
93  for (ivec = 0; ivec < nvec; ivec += 1)
94  set_rotation_x(m_rotation_x, angle)
95  w_temp_rotate_x = inout[p][ivec]
96  matrixop /free w_temp_rotate_x_result = m_rotation_x x w_temp_rotate_x
97  inout[][ivec] = w_temp_rotate_x_result[p]
98  endfor
99 end
100 
101 function rotate_y_wave(inout, angle)
102  // rotates a wave of 3-vectors about the y axis
103  wave inout // wave with dimensions (3, N), N >= 1, (x, y, z)
104  // result will be in same wave
105  variable angle // rotation angle in degrees
106 
107  wave m_rotation_y = create_rotation_matrix_free()
108  make /n=3/d/free w_temp_rotate_y
109  variable ivec, nvec
110  nvec = max(DimSize(inout, 1), 1)
111  for (ivec = 0; ivec < nvec; ivec += 1)
112  set_rotation_y(m_rotation_y, angle)
113  w_temp_rotate_y = inout[p][ivec]
114  matrixop /free w_temp_rotate_y_result = m_rotation_y x w_temp_rotate_y
115  inout[][ivec] = w_temp_rotate_y_result[p]
116  endfor
117 end
118 
119 function rotate_z_wave(inout, angle)
120  // rotates a wave of 3-vectors about the z axis
121  wave inout // wave with dimensions (3, N), N >= 1, (x, y, z)
122  // result will be in same wave
123  variable angle // rotation angle in degrees
124 
125  wave m_rotation_z = create_rotation_matrix_free()
126  make /n=3/d/free w_temp_rotate_z
127  variable ivec, nvec
128  nvec = max(DimSize(inout, 1), 1)
129  for (ivec = 0; ivec < nvec; ivec += 1)
130  set_rotation_z(m_rotation_z, angle)
131  w_temp_rotate_z = inout[p][ivec]
132  matrixop /free w_temp_rotate_z_result = m_rotation_z x w_temp_rotate_z
133  inout[][ivec] = w_temp_rotate_z_result[p]
134  endfor
135 end
wave set_rotation_x(wave matrix, variable angle)
+
variable rotate_x_wave(wave inout, variable angle)
+
variable rotate2d_x(variable xx, variable yy, variable angle)
+
wave set_rotation_z(wave matrix, variable angle)
+
variable rotate_y_wave(wave inout, variable angle)
+
variable rotate2d_y(variable xx, variable yy, variable angle)
+
variable rotate_z_wave(wave inout, variable angle)
+
wave create_rotation_matrix_free()
+
wave set_rotation_y(wave matrix, variable angle)
+
- + - - + + + +
- + - - + + + +
- + - + + + +