Compare commits
3 Commits
rev-distro
...
rev-distro
Author | SHA1 | Date | |
---|---|---|---|
c8a69460bc | |||
600061f684 | |||
0dc6ca820b |
@ -11,10 +11,12 @@ PEARL Procedures should be installed according to the regular Igor Pro guideline
|
||||
|
||||
- Make a `pearl-procs` directory in your private or shared `User Procedures` folder, and copy the PEARL Procedures distribution there.
|
||||
- Create shortcuts of the `pearl-arpes.ipf` and `pearl-menu.ipf` files, and move them to the `Igor Procedures` folder next to your `User Procedures` folder.
|
||||
- Find the `HDF5.XOP` extension in the `Igor Pro Folder` under `More Extensions/File Loaders`, create a shortcut, and move the shortcut to the `Igor Extensions` folder next to your `User Procedures` folder.
|
||||
- Find the `HDF5.XOP` (`HDF5-64.xop` for Igor 7 64-bit) extension in the `Igor Pro Folder` under `More Extensions/File Loaders` (`More Extensions (64-bit)/File Loaders`), create a shortcut, and move the shortcut to the `Igor Extensions` folder next to your `User Procedures` folder.
|
||||
- Find the `HDF5 Help.ihf` next to `HDF5.XOP`, create a shortcut, and move the shortcut to the `Igor Help Files` folder next to your `User Procedures` folder.
|
||||
|
||||
PEARL Procedures has been tested under Igor Pro version 6.37 (32-bit). Older versions (particularly prior to 6.34) may not be compatible. Please update to the latest Igor Pro version before reporting any problems.
|
||||
PEARL Procedures has been tested under Igor Pro version 6.37 (32-bit). Older versions prior to 6.36 are not be compatible. Please update to the latest Igor Pro 6 version before reporting any problems.
|
||||
|
||||
PEARL Procedures compiles under Igor 7.00. Some features, in particular 3D graphics, may not work properly.
|
||||
|
||||
|
||||
License
|
||||
|
@ -6,14 +6,14 @@
|
||||
#include "pearl-polar-coordinates"
|
||||
#include <New Polar Graphs>
|
||||
|
||||
// $Id$
|
||||
//
|
||||
// copyright (c) 2013-15 Paul Scherrer Institut
|
||||
// copyright (c) 2013-16 Paul Scherrer Institut
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http:///www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Please acknowledge the use of this code.
|
||||
|
||||
/// @file
|
||||
/// @brief processing and holographic mapping of angle scanned XPD data.
|
||||
@ -64,7 +64,7 @@
|
||||
///
|
||||
/// @author matthias muntwiler, matthias.muntwiler@psi.ch
|
||||
///
|
||||
/// @copyright 2013-15 Paul Scherrer Institut @n
|
||||
/// @copyright 2013-16 Paul Scherrer Institut @n
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License"); @n
|
||||
/// you may not use this file except in compliance with the License. @n
|
||||
/// You may obtain a copy of the License at
|
||||
@ -79,15 +79,38 @@
|
||||
///
|
||||
/// PearlAnglescanProcess is declared in @ref pearl-anglescan-process.ipf.
|
||||
|
||||
/// @warning experimental
|
||||
function strip_remove_frames(strip, yscale, ylo, yhi)
|
||||
|
||||
/// delete a contiguous range of frames from a strip.
|
||||
///
|
||||
/// this can be used to remove a region of bad frames due to, e.g., measurement problems.
|
||||
/// the function operates on 2D intensity data and manipulator coordinates at the same time.
|
||||
///
|
||||
/// @param[in,out] strip 2D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan.
|
||||
/// the result is written to the original wave.
|
||||
///
|
||||
/// @param[in,out] theta 1D data, manipulator scan.
|
||||
/// the result is written to the original wave.
|
||||
///
|
||||
/// @param[in,out] tilt 1D data, manipulator scan.
|
||||
/// the result is written to the original wave.
|
||||
///
|
||||
/// @param[in,out] phi 1D data, manipulator scan.
|
||||
/// the result is written to the original wave.
|
||||
///
|
||||
/// @param[in] qlo point index of first frame to delete.
|
||||
///
|
||||
/// @param[in] qhi point index of last frame to delete.
|
||||
/// qhi must be greater or equal than qlo.
|
||||
///
|
||||
function strip_delete_frames(strip, qlo, qhi, theta, tilt, phi)
|
||||
wave strip // 2D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan
|
||||
wave /z yscale // Y scaling, e.g. ManipulatorPhi
|
||||
// if unassigned, point scaling is assumed
|
||||
variable ylo
|
||||
variable yhi
|
||||
variable qlo
|
||||
variable qhi
|
||||
wave theta
|
||||
wave tilt
|
||||
wave phi
|
||||
|
||||
if (ylo > yhi)
|
||||
if (qlo > qhi)
|
||||
return -1
|
||||
endif
|
||||
|
||||
@ -95,8 +118,8 @@ function strip_remove_frames(strip, yscale, ylo, yhi)
|
||||
variable snx = dimsize(strip, 0)
|
||||
variable sny = dimsize(strip, 1)
|
||||
variable sq1lo = 0
|
||||
variable sq1hi = max(round((ylo - dimoffset(strip, 1)) / dimdelta(strip, 1)), 0)
|
||||
variable sq2lo = min(round((ylo - dimoffset(strip, 1)) / dimdelta(strip, 1)), sny - 1)
|
||||
variable sq1hi = max(qlo-1, 0)
|
||||
variable sq2lo = min(qhi+1, sny - 1)
|
||||
variable sq2hi = dimsize(strip, 1) - 1
|
||||
|
||||
// dest indices
|
||||
@ -111,10 +134,24 @@ function strip_remove_frames(strip, yscale, ylo, yhi)
|
||||
|
||||
duplicate /free strip, strip_copy
|
||||
redimension /n=(dnx,dny) strip
|
||||
|
||||
strip[][dq1lo,dq1hi] = strip_copy[p][q + q1ofs]
|
||||
strip[][dq2lo,dq2hi] = strip_copy[p][q + q2ofs]
|
||||
|
||||
duplicate /free theta, theta_copy
|
||||
redimension /n=(dny) theta
|
||||
theta[dq1lo,dq1hi] = theta_copy[p + q1ofs]
|
||||
theta[dq2lo,dq2hi] = theta_copy[p + q2ofs]
|
||||
|
||||
duplicate /free tilt, tilt_copy
|
||||
redimension /n=(dny) tilt
|
||||
tilt[dq1lo,dq1hi] = tilt_copy[p + q1ofs]
|
||||
tilt[dq2lo,dq2hi] = tilt_copy[p + q2ofs]
|
||||
|
||||
duplicate /free phi, phi_copy
|
||||
redimension /n=(dny) phi
|
||||
phi[dq1lo,dq1hi] = phi_copy[p + q1ofs]
|
||||
phi[dq2lo,dq2hi] = phi_copy[p + q2ofs]
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
@ -144,6 +181,7 @@ end
|
||||
/// @return if check waves are enabled, the following waves are created (overwritten if existing):
|
||||
/// @arg check_dist average X distribution
|
||||
/// @arg check_smoo smoothed distribution used to normalize the strip
|
||||
///
|
||||
function normalize_strip_x(strip, [smooth_method, smooth_factor, check])
|
||||
wave strip
|
||||
variable smooth_method
|
||||
@ -233,6 +271,7 @@ end
|
||||
/// @return if check waves are enabled, the following waves are created (overwritten if existing):
|
||||
/// @arg check_dist average theta distribution
|
||||
/// @arg check_smoo smoothed distribution used to normalize the strip
|
||||
///
|
||||
function normalize_strip_theta(strip, theta, [theta_offset, smooth_method, smooth_factor, check])
|
||||
wave strip
|
||||
wave theta
|
||||
@ -300,6 +339,70 @@ function normalize_strip_theta(strip, theta, [theta_offset, smooth_method, smoot
|
||||
endif
|
||||
end
|
||||
|
||||
/// divide the strip by a two-dimensional normalization function.
|
||||
///
|
||||
/// @warning experimental. this function is under development.
|
||||
///
|
||||
/// @param check enable output of intermediate results
|
||||
/// @arg 0 (default) don't create additional waves
|
||||
/// @arg 1 create check waves in the current folder
|
||||
/// @arg 2 calculate check waves only, do not modify strip
|
||||
///
|
||||
/// @return if check waves are enabled, the following waves are created (overwritten if existing):
|
||||
/// @arg check_dist average theta distribution
|
||||
/// @arg check_smoo smoothed distribution used to normalize the strip
|
||||
///
|
||||
function normalize_strip_2d(strip, theta, [theta_offset, smooth_method, smooth_factor, check])
|
||||
wave strip
|
||||
wave theta
|
||||
variable theta_offset
|
||||
variable smooth_method
|
||||
variable smooth_factor
|
||||
variable check
|
||||
|
||||
if (ParamIsDefault(check))
|
||||
check = 0
|
||||
endif
|
||||
if (ParamIsDefault(theta_offset))
|
||||
theta_offset = 0
|
||||
endif
|
||||
if (ParamIsDefault(smooth_method))
|
||||
smooth_method = 4
|
||||
endif
|
||||
if (ParamIsDefault(smooth_factor))
|
||||
smooth_factor = 0.5
|
||||
endif
|
||||
|
||||
variable nx = dimsize(strip, 0)
|
||||
variable ny = dimsize(strip, 1)
|
||||
|
||||
duplicate /free strip, dist, alpha_int, theta_int
|
||||
theta_int = theta[q] - theta_offset
|
||||
alpha_int = dimoffset(strip, 0) + p * dimdelta(strip, 0)
|
||||
redimension /n=(nx * ny) dist, alpha_int, theta_int
|
||||
|
||||
switch(smooth_method)
|
||||
case 4:
|
||||
loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={alpha_int, theta_int}
|
||||
redimension /n=(nx, ny) dist_smoo
|
||||
break
|
||||
default:
|
||||
Abort "undefined smooth method"
|
||||
break
|
||||
endswitch
|
||||
|
||||
// divide
|
||||
if (check != 2)
|
||||
strip /= dist_smoo
|
||||
endif
|
||||
|
||||
// check
|
||||
if (check)
|
||||
//duplicate /o dist, check_dist
|
||||
duplicate /o dist_smoo, check_smoo
|
||||
endif
|
||||
end
|
||||
|
||||
/// crop a strip at the sides.
|
||||
///
|
||||
/// the strip is cropped in place, data outside the region of interest is lost.
|
||||
@ -705,9 +808,9 @@ function convert_angles_ttpa2polar(theta, tilt, phi, analyser, polar, azi)
|
||||
// this is simply a polar-cartesian mapping, independent of the manipulator
|
||||
// phi=0 is in the polar rotation plane
|
||||
make /n=(3,na) /d /free w_orig_polar, w_orig_cart, w_rot_cart, w_rot_polar
|
||||
w_orig_polar[0] = radius
|
||||
w_orig_polar[1] = analyser[q]
|
||||
w_orig_polar[2] = 0
|
||||
w_orig_polar[0][] = radius
|
||||
w_orig_polar[1][] = analyser[q]
|
||||
w_orig_polar[2][] = 0
|
||||
polar2cart_wave(w_orig_polar, w_orig_cart)
|
||||
// if the angle-dispersive axis was horizontal, we'd need to rotate the detector
|
||||
//rotate_z_wave(w_orig_cart, 90)
|
||||
@ -1802,21 +1905,46 @@ function /s display_scanlines(nickname, alpha_lo, alpha_hi, m_theta, m_tilt, m_p
|
||||
return graphname
|
||||
end
|
||||
|
||||
static constant kProjScaleLinear = 2
|
||||
/// @page PageProjections 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.
|
||||
///
|
||||
constant kProjDist = 0
|
||||
constant kProjStereo = 1
|
||||
constant kProjArea = 2
|
||||
constant kProjGnom = 3
|
||||
constant kProjOrtho = 4
|
||||
|
||||
static constant kProjScaleDist = 2
|
||||
static constant kProjScaleStereo = 2
|
||||
static constant kProjScaleAzim = 2
|
||||
static constant kProjScaleArea = 2
|
||||
// scaled so that radius(gnom) = radius(stereo) for polar = 88
|
||||
static constant kProjScaleGnomonic = 0.06744519021
|
||||
static constant kProjScaleGnom = 0.06744519021
|
||||
static constant kProjScaleOrtho = 2
|
||||
|
||||
/// calculate the projected polar angle
|
||||
///
|
||||
/// @param polar polar angle in degrees
|
||||
///
|
||||
/// @param projection mapping function from polar to cartesian coordinates
|
||||
/// @arg 0 linear
|
||||
/// @arg 1 stereographic (default)
|
||||
/// @arg 2 azimuthal
|
||||
/// @arg 3 gnomonic (0 <= polar < 90)
|
||||
/// @param projection mapping function from polar to cartesian coordinates.
|
||||
/// see @ref PageProjections for details.
|
||||
/// @arg kProjDist = 0 azimuthal equidistant
|
||||
/// @arg kProjStereo = 1 stereographic (default)
|
||||
/// @arg kProjArea = 2 azimuthal equal-area
|
||||
/// @arg kProjGnom = 3 gnomonic (0 <= polar < 90)
|
||||
/// @arg kProjOrtho = 4 orthographic
|
||||
///
|
||||
/// @return projected radius.
|
||||
/// the radius is scaled such that grazing emission maps to 2.
|
||||
@ -1830,17 +1958,20 @@ threadsafe function calc_graph_radius(polar, [projection])
|
||||
|
||||
variable radius
|
||||
switch(projection)
|
||||
case 1: // stereographic
|
||||
case kProjStereo: // stereographic
|
||||
radius = kProjScaleStereo * tan(polar / 2 * pi / 180)
|
||||
break
|
||||
case 2: // azimuthal
|
||||
radius = kProjScaleAzim * cos((180 - polar) / 2 * pi / 180)
|
||||
case kProjArea: // equal area
|
||||
radius = kProjScaleArea * sin(polar / 2 * pi / 180)
|
||||
break
|
||||
case 3: // gnomonic
|
||||
radius = polar < 90 ? kProjScaleGnomonic * tan(polar * pi / 180) : inf
|
||||
case kProjGnom: // gnomonic
|
||||
radius = polar < 90 ? kProjScaleGnom * tan(polar * pi / 180) : inf
|
||||
break
|
||||
default: // linear
|
||||
radius = kProjScaleLinear * polar / 90
|
||||
case kProjOrtho: // orthographic
|
||||
radius = kProjScaleOrtho * sin(polar * pi / 180)
|
||||
break
|
||||
default: // equidistant
|
||||
radius = kProjScaleDist * polar / 90
|
||||
endswitch
|
||||
|
||||
return radius
|
||||
@ -1852,10 +1983,13 @@ end
|
||||
///
|
||||
/// @param x, y projected Cartesian coordinate
|
||||
///
|
||||
/// @param projection mapping function from polar to cartesian coordinates
|
||||
/// @arg 0 linear
|
||||
/// @arg 1 stereographic (default)
|
||||
/// @arg 2 azimuthal
|
||||
/// @param projection mapping function from polar to cartesian coordinates.
|
||||
/// see @ref PageProjections for details.
|
||||
/// @arg kProjDist = 0 azimuthal equidistant
|
||||
/// @arg kProjStereo = 1 stereographic (default)
|
||||
/// @arg kProjArea = 2 azimuthal equal-area
|
||||
/// @arg kProjGnom = 3 gnomonic (0 <= polar < 90)
|
||||
/// @arg kProjOrtho = 4 orthographic
|
||||
///
|
||||
/// @returns polar angle in degrees
|
||||
///
|
||||
@ -1873,17 +2007,20 @@ threadsafe function calc_graph_polar(x, y, [projection])
|
||||
|
||||
radius = sqrt(x^2 + y^2)
|
||||
switch(projection)
|
||||
case 1: // stereographic
|
||||
case kProjStereo: // stereographic
|
||||
polar = 2 * atan(radius / kProjScaleStereo) * 180 / pi
|
||||
break
|
||||
case 2: // azimuthal
|
||||
polar = 180 - 2 * acos(radius / kProjScaleAzim) * 180 / pi
|
||||
case kProjArea: // equal area
|
||||
polar = 2 * asin(radius / kProjScaleArea) * 180 / pi
|
||||
break
|
||||
case 3: // gnomonic
|
||||
polar = atan(radius / kProjScaleGnomonic) * 180 / pi
|
||||
case kProjGnom: // gnomonic
|
||||
polar = atan(radius / kProjScaleGnom) * 180 / pi
|
||||
break
|
||||
default: // linear
|
||||
polar = 90 * radius / kProjScaleLinear
|
||||
case kProjOrtho: // orthographic
|
||||
polar = asin(radius / kProjScaleOrtho) * 180 / pi
|
||||
break
|
||||
default: // equidistant
|
||||
polar = 90 * radius / kProjScaleDist
|
||||
endswitch
|
||||
|
||||
return polar
|
||||
@ -1894,10 +2031,13 @@ end
|
||||
/// @param x, y projected Cartesian coordinate
|
||||
///
|
||||
/// @param projection mapping function from polar to cartesian coordinates.
|
||||
/// projections 0-2 have no effect on the azimuthal coordinate.
|
||||
/// @arg 0 linear
|
||||
/// @arg 1 stereographic (default)
|
||||
/// @arg 2 azimuthal
|
||||
/// all supported projections are azimuthal, they have no effect on the azimuthal coordinate.
|
||||
/// see @ref PageProjections for details.
|
||||
/// @arg kProjDist = 0 azimuthal equidistant
|
||||
/// @arg kProjStereo = 1 stereographic (default)
|
||||
/// @arg kProjArea = 2 azimuthal equal-area
|
||||
/// @arg kProjGnom = 3 gnomonic (0 <= polar < 90)
|
||||
/// @arg kProjOrtho = 4 orthographic
|
||||
///
|
||||
/// @param zeroAngle zeroAngleWhere parameter of polar graphs
|
||||
/// @arg 0 (default) zero is at the 3 o'clock position
|
||||
@ -2483,4 +2623,158 @@ function import_tpi_scan(nickname, theta, phi, intensity, [folding, npolar, nogr
|
||||
endfor
|
||||
|
||||
display_hemi_scan(nickname)
|
||||
end
|
||||
end
|
||||
|
||||
/// extract a polar cut from a hemispherical scan.
|
||||
///
|
||||
/// for each polar angle, the function first extracts all azimuthal angles.
|
||||
/// the intensity is then interpolated between the nearest neighbours of the given azimuth.
|
||||
///
|
||||
/// the hemi grid must have been created in the current data folder by the make_hemi_grid function.
|
||||
/// correct ordering is required.
|
||||
///
|
||||
/// @param nickname name of the scan dataset.
|
||||
/// can be empty if no prefix is used.
|
||||
/// the dataset must be in the current datafolder.
|
||||
///
|
||||
/// @param azim azimuthal angle in degrees
|
||||
///
|
||||
/// @return reference of the created wave.
|
||||
/// the wave has the same name as the intensity wave of the dataset
|
||||
/// with the suffix "_azi" and the azimuthal angle rounded to integer.
|
||||
/// it is created in the same datafolder as the original data.
|
||||
///
|
||||
function /wave hemi_polar_cut(nickname, azim)
|
||||
string nickname
|
||||
variable azim
|
||||
|
||||
if (strlen(nickname))
|
||||
string s_prefix = nickname + "_"
|
||||
string s_int = s_prefix + "i"
|
||||
else
|
||||
s_prefix = ""
|
||||
s_int = "values"
|
||||
endif
|
||||
string s_totals = s_prefix + "tot"
|
||||
string s_weights = s_prefix + "wt"
|
||||
string s_polar = s_prefix + "pol"
|
||||
string s_azim = s_prefix + "az"
|
||||
string s_index = s_prefix + "index"
|
||||
string s_theta = s_prefix + "th"
|
||||
string s_dphi = s_prefix + "dphi"
|
||||
string s_nphis = s_prefix + "nphis"
|
||||
string s_cut
|
||||
sprintf s_cut, "%s_azi%03u", s_int, round(azim)
|
||||
|
||||
wave w_polar = $s_polar
|
||||
wave w_azim = $s_azim
|
||||
wave w_values = $s_int
|
||||
wave w_totals = $s_totals
|
||||
wave w_weights = $s_weights
|
||||
wave w_index = $s_index
|
||||
wave w_theta = $s_theta
|
||||
wave w_dphi = $s_dphi
|
||||
wave w_nphis = $s_nphis
|
||||
|
||||
variable npol = numpnts(w_theta)
|
||||
variable ipol
|
||||
variable pol_st = abs(w_theta[1] - w_theta[0])
|
||||
variable pol
|
||||
variable pol1, pol2
|
||||
variable nsel
|
||||
make /n=(npol) /o $s_cut
|
||||
wave w_cut = $s_cut
|
||||
setscale /i x w_theta[0], w_theta[numpnts(w_theta)-1], "deg", w_cut
|
||||
make /n=1 /free azi_slice
|
||||
make /n=1 /free values_slice
|
||||
|
||||
for (ipol = 0; ipol < npol; ipol += 1)
|
||||
pol = w_theta[ipol]
|
||||
pol1 = pol - pol_st / 2
|
||||
pol2 = pol + pol_st / 2
|
||||
extract /free /indx w_polar, sel, (pol1 < w_polar) && (w_polar <= pol2)
|
||||
nsel = numpnts(sel)
|
||||
if (nsel > 0)
|
||||
redimension /n=(nsel+2) azi_slice, values_slice
|
||||
azi_slice[1, nsel] = w_azim[sel[p-1]]
|
||||
azi_slice[0] = azi_slice[nsel] - 360
|
||||
azi_slice[nsel+1] = azi_slice[1] + 360
|
||||
values_slice[1, nsel] = w_values[sel[p-1]]
|
||||
values_slice[0] = values_slice[nsel]
|
||||
values_slice[nsel+1] = values_slice[1]
|
||||
w_cut[ipol] = interp(azim, azi_slice, values_slice)
|
||||
else
|
||||
w_cut[ipol] = nan
|
||||
endif
|
||||
endfor
|
||||
return w_cut
|
||||
end
|
||||
|
||||
/// extract an azimuthal cut from a hemispherical scan
|
||||
///
|
||||
/// the function extracts all azimuthal angles that are present for the given polar angle.
|
||||
///
|
||||
/// the hemi grid must have been created in the current data folder by the make_hemi_grid function.
|
||||
/// correct ordering is required.
|
||||
///
|
||||
/// @param nickname name of the scan dataset.
|
||||
/// can be empty if no prefix is used.
|
||||
/// the dataset must be in the current datafolder.
|
||||
///
|
||||
/// @param pol polar angle in degrees
|
||||
///
|
||||
/// @return reference of the created wave.
|
||||
/// the wave has the same name as the intensity wave of the dataset
|
||||
/// with the suffix "_azi" and the azimuthal angle rounded to integer.
|
||||
/// it is created in the same datafolder as the original data.
|
||||
///
|
||||
function /wave hemi_azi_cut(nickname, pol)
|
||||
string nickname
|
||||
variable pol
|
||||
|
||||
if (strlen(nickname))
|
||||
string s_prefix = nickname + "_"
|
||||
string s_int = s_prefix + "i"
|
||||
else
|
||||
s_prefix = ""
|
||||
s_int = "values"
|
||||
endif
|
||||
string s_totals = s_prefix + "tot"
|
||||
string s_weights = s_prefix + "wt"
|
||||
string s_polar = s_prefix + "pol"
|
||||
string s_azim = s_prefix + "az"
|
||||
string s_index = s_prefix + "index"
|
||||
string s_theta = s_prefix + "th"
|
||||
string s_dphi = s_prefix + "dphi"
|
||||
string s_nphis = s_prefix + "nphis"
|
||||
string s_cut
|
||||
sprintf s_cut, "%s_pol%03u", s_int, round(pol)
|
||||
|
||||
wave w_polar = $s_polar
|
||||
wave w_azim = $s_azim
|
||||
wave w_values = $s_int
|
||||
wave w_totals = $s_totals
|
||||
wave w_weights = $s_weights
|
||||
wave w_index = $s_index
|
||||
wave w_theta = $s_theta
|
||||
wave w_dphi = $s_dphi
|
||||
wave w_nphis = $s_nphis
|
||||
|
||||
variable pol_st = abs(w_theta[1] - w_theta[0])
|
||||
variable pol1, pol2
|
||||
variable nsel
|
||||
|
||||
pol1 = pol - pol_st / 2
|
||||
pol2 = pol + pol_st / 2
|
||||
extract /free /indx w_polar, sel, (pol1 < w_polar) && (w_polar <= pol2)
|
||||
nsel = numpnts(sel)
|
||||
if (nsel > 0)
|
||||
make /n=(nsel) /o $s_cut
|
||||
wave w_cut = $s_cut
|
||||
w_cut = w_values[sel]
|
||||
setscale /i x w_azim[sel[0]], w_azim[sel[nsel-1]], "deg", w_cut
|
||||
return w_cut
|
||||
else
|
||||
return $""
|
||||
endif
|
||||
end
|
||||
|
@ -52,6 +52,25 @@
|
||||
/// PearlAreaDisplay is declared in @ref pearl-area-display.ipf.
|
||||
///
|
||||
|
||||
/// compose a valid and unique graph name from a data folder reference
|
||||
static function /s graphname_from_dfref(df, prefix)
|
||||
dfref df
|
||||
string prefix
|
||||
|
||||
string name
|
||||
|
||||
name = GetDataFolder(1, df)
|
||||
name = ReplaceString("root:", name, "")
|
||||
name = name[0, strlen(name) - 2]
|
||||
name = ReplaceString(" ", name, "")
|
||||
name = CleanupName(prefix + name, 0)
|
||||
if (CheckName(name, 6))
|
||||
name = UniqueName(name, 6, 0)
|
||||
endif
|
||||
|
||||
return name
|
||||
end
|
||||
|
||||
/// open a new graph window with a 2D image.
|
||||
///
|
||||
/// this is essentially <code>display; appendimage</code>.
|
||||
@ -72,7 +91,7 @@ function /s ad_display(image)
|
||||
|
||||
string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
|
||||
string graphtitle = dfname + " View"
|
||||
string /g view_graphname = CleanupName("view_" + dfname, 0)
|
||||
string /g view_graphname = graphname_from_dfref(imagedf, "view_")
|
||||
svar graphname = view_graphname
|
||||
display /k=1/n=$graphname as graphtitle
|
||||
graphname = s_name
|
||||
@ -104,7 +123,7 @@ function /s ad_display_histogram(image)
|
||||
|
||||
string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
|
||||
string graphtitle = dfname + " Histogram"
|
||||
string /g hist_graphname = CleanupName("hist_" + dfname, 0)
|
||||
string /g hist_graphname = graphname_from_dfref(imagedf, "hist_")
|
||||
svar graphname = hist_graphname
|
||||
display /k=1/n=$graphname as graphtitle
|
||||
graphname = s_name
|
||||
@ -177,9 +196,9 @@ function /s ad_display_profiles(image, [filter])
|
||||
view_filter_options = ""
|
||||
variable /g view_filter_smoothing_x = 1
|
||||
variable /g view_filter_smoothing_y = 1
|
||||
string dfname = GetDataFolder(0, imagedf)
|
||||
string graphtitle = dfname + ":" + NameOfWave(image) + " Profiles"
|
||||
string /g prof_graphname = CleanupName("prof_" + dfname, 0)
|
||||
string dfname = ReplaceString("root:", GetDataFolder(1, imagedf), "")
|
||||
string graphtitle = dfname + NameOfWave(image) + " Profiles"
|
||||
string /g prof_graphname = graphname_from_dfref(imagedf, "prof_")
|
||||
svar graphname = prof_graphname
|
||||
variable /g graph_avg // average value in ROI (ROI is defined by the crosshairs A and B)
|
||||
variable /g graph_min // minimum value in ROI
|
||||
@ -1004,7 +1023,7 @@ function /s ad_display_brick(data)
|
||||
setdatafolder viewdf
|
||||
string dfname = ReplaceString("root:", s_datadf, "")
|
||||
string graphtitle = dfname + " Gizmo"
|
||||
string /g gizmo_graphname = CleanupName("giz_" + dfname, 0)
|
||||
string /g gizmo_graphname = graphname_from_dfref(datadf, "giz_")
|
||||
svar graphname = gizmo_graphname
|
||||
|
||||
if ((strlen(graphname) > 0) && (wintype(graphname) == 13))
|
||||
|
@ -1450,7 +1450,7 @@ static function bp_dataset_folder(ba) : ButtonControl
|
||||
string cmd
|
||||
sprintf cmd, "setdatafolder root:%s", PossiblyQuoteName(dataset)
|
||||
execute /q /z cmd
|
||||
cmd = "setdatafolder :scan_1"
|
||||
cmd = "setdatafolder :scan1"
|
||||
execute /q /z cmd
|
||||
sprintf cmd, "setdatafolder %s", GetDataFolder(1)
|
||||
print cmd
|
||||
|
@ -454,7 +454,7 @@ function Au4f(w, x): fitfunc
|
||||
vc1 = w[ip] / sqrt(pi) * vc2
|
||||
vc3 = w[ip+1]
|
||||
vc4 = vc2 * w[ip+2] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
endfor
|
||||
|
||||
return v
|
||||
@ -491,25 +491,25 @@ function Au4f_2p2(w, x): fitfunc
|
||||
vc1 = w[3] / sqrt(pi) * vc2
|
||||
vc3 = w[4]
|
||||
vc4 = vc2 * w[5] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
// 5/2 surface
|
||||
vc1 = w[3] / sqrt(pi) * vc2 * w[9]
|
||||
vc3 = w[4] + w[10]
|
||||
vc4 = vc2 * w[5] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
// 7/2 bulk
|
||||
vc1 = w[6] / sqrt(pi) * vc2
|
||||
vc3 = w[7]
|
||||
vc4 = vc2 * w[8] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
// 7/2 surface
|
||||
vc1 = w[6] / sqrt(pi) * vc2 * w[9]
|
||||
vc3 = w[7] + w[10]
|
||||
vc4 = vc2 * w[8] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
return v
|
||||
|
||||
@ -578,37 +578,37 @@ function Au4f_2p3(w, x): fitfunc
|
||||
vc1 = w[3] / sqrt(pi) * vc2
|
||||
vc3 = w[4]
|
||||
vc4 = vc2 * w[5] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
// 5/2 surface
|
||||
vc1 = w[3] / sqrt(pi) * vc2 * w[9]
|
||||
vc3 = w[4] + w[10]
|
||||
vc4 = vc2 * w[5] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
// 5/2 2nd layer
|
||||
vc1 = w[3] / sqrt(pi) * vc2 * w[11]
|
||||
vc3 = w[4] + w[12]
|
||||
vc4 = vc2 * w[5] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
// 7/2 bulk
|
||||
vc1 = w[6] / sqrt(pi) * vc2
|
||||
vc3 = w[7]
|
||||
vc4 = vc2 * w[8] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
// 7/2 surface
|
||||
vc1 = w[6] / sqrt(pi) * vc2 * w[9]
|
||||
vc3 = w[7] + w[10]
|
||||
vc4 = vc2 * w[8] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
// 7/2 2nd layer
|
||||
vc1 = w[6] / sqrt(pi) * vc2 * w[11]
|
||||
vc3 = w[7] + w[12]
|
||||
vc4 = vc2 * w[8] / 2
|
||||
v += vc1 * Voigt(vc2 * (x - vc3), vc4)
|
||||
v += vc1 * VoigtFunc(vc2 * (x - vc3), vc4)
|
||||
|
||||
return v
|
||||
|
||||
|
@ -66,6 +66,15 @@ strconstant kScanDimLabel = "scan"
|
||||
/// This label may be used to store the parameters for the `setscale d` operation.
|
||||
strconstant kDataDimLabel = "data"
|
||||
|
||||
/// List of preferred datasets to load for preview
|
||||
strconstant kPreviewDatasets = "ScientaImage;ScientaSpectrum;ImageAngleDistribution;ImageEnergyDistribution;Counts;SampleCurrent;"
|
||||
|
||||
/// List of datasets that must be loaded to determine the axis scaling of a Scienta image
|
||||
strconstant kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;"
|
||||
|
||||
/// List of datasets that should be transposed upon loading
|
||||
strconstant kTransposedDatasets = "ScientaImage;"
|
||||
|
||||
/// 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,
|
||||
@ -183,7 +192,9 @@ function /s psh5_load_complete(ANickName, APathName, AFileName, [load_data, load
|
||||
|
||||
for (ig = 0; ig < ng; ig += 1)
|
||||
sg = StringFromList(ig, s_scanpaths, ";")
|
||||
folder = CleanupName(ReplaceString("/", sg, ""), 0)
|
||||
folder = ReplaceString("/", sg, "")
|
||||
folder = ReplaceString(" ", folder, "")
|
||||
folder = CleanupName(folder, 0)
|
||||
setdatafolder fileDF
|
||||
newdatafolder /s /o $folder
|
||||
psh5_load_scan_complete(fileID, sg, load_data=load_data, load_attr=load_attr)
|
||||
@ -219,14 +230,26 @@ end
|
||||
/// @param load_attr 1 (default): load attributes; 0: do not load attributes
|
||||
/// note: for correct scaling of the image, the attributes need to be loaded
|
||||
///
|
||||
/// @param pref_scans semicolon-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.
|
||||
///
|
||||
/// @param pref_datasets semicolon-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.
|
||||
///
|
||||
/// @return name of loaded preview wave.
|
||||
///
|
||||
function /s psh5_load_preview(ANickName, APathName, AFileName, [load_data, load_attr])
|
||||
function /s psh5_load_preview(ANickName, APathName, AFileName, [load_data, load_attr, pref_scans, pref_datasets])
|
||||
string ANickName
|
||||
string APathName
|
||||
string AFileName
|
||||
variable load_data
|
||||
variable load_attr
|
||||
string pref_scans
|
||||
string pref_datasets
|
||||
|
||||
if (ParamIsDefault(load_data))
|
||||
load_data = 1
|
||||
@ -234,7 +257,13 @@ function /s psh5_load_preview(ANickName, APathName, AFileName, [load_data, load_
|
||||
if (ParamIsDefault(load_attr))
|
||||
load_attr = 1
|
||||
endif
|
||||
|
||||
if (ParamIsDefault(pref_scans))
|
||||
pref_scans = "*scan1*;"
|
||||
endif
|
||||
if (ParamIsDefault(pref_datasets))
|
||||
pref_datasets = ""
|
||||
endif
|
||||
|
||||
dfref saveDF = GetDataFolderDFR()
|
||||
setdatafolder root:
|
||||
newdatafolder /o/s pearl_area
|
||||
@ -253,26 +282,53 @@ function /s psh5_load_preview(ANickName, APathName, AFileName, [load_data, load_
|
||||
if (v_flag == 0)
|
||||
AFileName = s_path + s_filename
|
||||
dfref fileDF = GetDataFolderDFR()
|
||||
|
||||
scanpaths = psh5_list_scans(fileID)
|
||||
variable ng = ItemsInList(scanpaths)
|
||||
variable ig
|
||||
string sg
|
||||
ig = 0
|
||||
sg = StringFromList(ig, scanpaths, ";")
|
||||
dataname = psh5_load_scan_preview(fileID, sg, set_scale=load_attr)
|
||||
variable np = ItemsInList(pref_scans)
|
||||
variable ip
|
||||
string sp
|
||||
variable found = 0
|
||||
if (ng > 0)
|
||||
for (ip = 0; ip < np; ip += 1)
|
||||
for (ig = 0; ig < ng; ig += 1)
|
||||
sg = StringFromList(ig, scanpaths)
|
||||
sp = StringFromList(ip, pref_scans)
|
||||
if (StringMatch(sg, sp))
|
||||
found = 1
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if (found)
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if (!found)
|
||||
ig = 0
|
||||
endif
|
||||
sg = StringFromList(ig, scanpaths)
|
||||
dataname = psh5_load_scan_preview(fileID, sg, set_scale=load_attr, pref_datasets=pref_datasets)
|
||||
|
||||
wave /z data = $dataname
|
||||
string destpath = GetDataFolder(1, saveDF) + ANickName
|
||||
if (waveexists(data))
|
||||
duplicate /o data, $destpath
|
||||
wave /z data = $destpath
|
||||
endif
|
||||
|
||||
if (load_attr)
|
||||
setdatafolder saveDF
|
||||
newdatafolder /o/s attr
|
||||
killwaves /a/z
|
||||
psh5_load_scan_attrs(fileID, sg)
|
||||
setdatafolder ::
|
||||
wave /z data = $dataname
|
||||
string destpath = GetDataFolder(1, saveDF) + ANickName
|
||||
if (waveexists(data))
|
||||
duplicate /o data, $destpath
|
||||
wave /z data = $destpath
|
||||
else
|
||||
print "no data found in file " + AFileName
|
||||
endif
|
||||
|
||||
if (load_attr)
|
||||
setdatafolder saveDF
|
||||
newdatafolder /o/s attr
|
||||
killwaves /a/z
|
||||
psh5_load_scan_attrs(fileID, sg)
|
||||
setdatafolder ::
|
||||
endif
|
||||
else
|
||||
print "no scans found in file " + AFileName
|
||||
endif
|
||||
|
||||
HDF5CloseFile fileID
|
||||
@ -396,6 +452,9 @@ end
|
||||
///
|
||||
/// data is loaded into the current data folder.
|
||||
///
|
||||
/// this function does not scale the datasets.
|
||||
/// call ps_scale_datasets() separately.
|
||||
///
|
||||
/// @param fileID ID of open HDF5 file from psh5_open_file().
|
||||
///
|
||||
/// @param scanpath path to the scan group in the HDF5 file, e.g. "/scan 1".
|
||||
@ -464,17 +523,21 @@ function /s psh5_load_scan_attrs(fileID, scanpath, [attr_sets])
|
||||
endif
|
||||
endif
|
||||
|
||||
variable ids
|
||||
variable nds
|
||||
string sds
|
||||
|
||||
if (attr_sets & 2)
|
||||
attr_list = AddListItem("LensMode", attr_list, ";", inf)
|
||||
attr_list = AddListItem("ScientaChannelBegin", attr_list, ";", inf)
|
||||
attr_list = AddListItem("ScientaChannelEnd", attr_list, ";", inf)
|
||||
attr_list = AddListItem("ScientaSliceBegin", attr_list, ";", inf)
|
||||
attr_list = AddListItem("ScientaSliceEnd", attr_list, ";", inf)
|
||||
nds = ItemsInList(kScientaScalingDatasets, ";")
|
||||
for (ids = 0; ids < nds; ids += 1)
|
||||
sds = StringFromList(ids, kScientaScalingDatasets)
|
||||
if (WhichListItem(sds, attr_list) < 0)
|
||||
attr_list = AddListItem(sds, attr_list, ";", inf)
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
|
||||
variable ids
|
||||
variable nds = ItemsInList(attr_list, ";")
|
||||
string sds
|
||||
nds = ItemsInList(attr_list, ";")
|
||||
string wavenames = ""
|
||||
for (ids = 0; ids < nds; ids += 1)
|
||||
sds = StringFromList(ids, attr_list, ";")
|
||||
@ -483,6 +546,7 @@ function /s psh5_load_scan_attrs(fileID, scanpath, [attr_sets])
|
||||
wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
|
||||
endif
|
||||
endfor
|
||||
wavenames = ReplaceString(";;", wavenames, ";")
|
||||
|
||||
return wavenames
|
||||
end
|
||||
@ -517,28 +581,29 @@ function /s psh5_load_scan_meta(fileID, scanpath)
|
||||
HDF5LoadData /O /Q /Z /A="Dimensions" /N=ScanDimensions /TYPE=1 fileID, scanpath
|
||||
if (!v_flag)
|
||||
wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
|
||||
HDF5LoadData /O /Q /Z /A="Writables" /N=ScanWritables /TYPE=1 fileID, scanpath
|
||||
if (!v_flag)
|
||||
wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
|
||||
endif
|
||||
HDF5LoadData /O /Q /Z /A="Readables" /N=ScanReadables /TYPE=1 fileID, scanpath
|
||||
if (!v_flag)
|
||||
wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
|
||||
endif
|
||||
HDF5LoadData /O /Q /Z /A="Steps" /N=ScanSteps /TYPE=1 fileID, scanpath
|
||||
if (!v_flag)
|
||||
wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
|
||||
endif
|
||||
else
|
||||
make /n=1 /o ScanDimensions
|
||||
ScanDimensions = 0
|
||||
wavenames = AddListItem("ScanDimensions", wavenames, ";", inf)
|
||||
endif
|
||||
HDF5LoadData /O /Q /Z /A="Readables" /N=ScanReadables /TYPE=1 fileID, scanpath
|
||||
if (!v_flag)
|
||||
wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
|
||||
else
|
||||
make /n=1 /o /t ScanReadables
|
||||
ScanReadables[0] = "ScientaSpectrum"
|
||||
wavenames = AddListItem("ScanReadables", wavenames, ";", inf)
|
||||
endif
|
||||
HDF5LoadData /O /Q /Z /A="Writables" /N=ScanWritables /TYPE=1 fileID, scanpath
|
||||
if (!v_flag)
|
||||
wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
|
||||
endif
|
||||
HDF5LoadData /O /Q /Z /A="Steps" /N=ScanSteps /TYPE=1 fileID, scanpath
|
||||
if (!v_flag)
|
||||
wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
|
||||
endif
|
||||
wavenames = ReplaceString(";;", wavenames, ";")
|
||||
|
||||
|
||||
return wavenames
|
||||
end
|
||||
|
||||
@ -573,6 +638,10 @@ function /s psh5_load_dataset(fileID, scanpath, datasetname, [set_scale])
|
||||
string datasetname
|
||||
variable set_scale
|
||||
|
||||
if (ParamIsDefault(set_scale))
|
||||
set_scale = 1
|
||||
endif
|
||||
|
||||
string datasetpath
|
||||
datasetpath = scanpath + "/" + datasetname
|
||||
datasetpath = ReplaceString("//", datasetpath, "/")
|
||||
@ -586,7 +655,7 @@ function /s psh5_load_dataset(fileID, scanpath, datasetname, [set_scale])
|
||||
endif
|
||||
|
||||
string dataname
|
||||
if (di.ndims < 3)
|
||||
if (di.ndims < 2)
|
||||
HDF5LoadData /O /Q /Z fileID, datasetpath
|
||||
dataname = StringFromList(0, S_waveNames)
|
||||
else
|
||||
@ -607,6 +676,56 @@ function /s psh5_load_dataset(fileID, scanpath, datasetname, [set_scale])
|
||||
return dataname
|
||||
end
|
||||
|
||||
/// select the preferred dataset from a list of available datasets.
|
||||
///
|
||||
/// @param file_datasets semicolon-separated list of datasets that are available in the file.
|
||||
///
|
||||
/// @param pref_datasets semicolon-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.
|
||||
///
|
||||
/// @return name of selected dataset.
|
||||
///
|
||||
static function /s select_dataset(file_datasets, pref_datasets)
|
||||
string file_datasets
|
||||
string pref_datasets
|
||||
|
||||
variable index
|
||||
variable nds = ItemsInList(file_datasets)
|
||||
variable ids
|
||||
string sds = ""
|
||||
variable np = ItemsInList(pref_datasets)
|
||||
variable ip
|
||||
string sp
|
||||
variable found = 0
|
||||
if (nds > 0)
|
||||
for (ip = 0; ip < np; ip += 1)
|
||||
for (ids = 0; ids < nds; ids += 1)
|
||||
sds = StringFromList(ids, file_datasets)
|
||||
index = ItemsInList(sds, "/") - 1
|
||||
sds = StringFromList(index, sds, "/")
|
||||
sp = StringFromList(ip, pref_datasets)
|
||||
if (StringMatch(sds, sp))
|
||||
found = 1
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if (found)
|
||||
break
|
||||
endif
|
||||
endfor
|
||||
if (!found)
|
||||
ids = 0
|
||||
sds = StringFromList(ids, file_datasets)
|
||||
index = ItemsInList(sds, "/") - 1
|
||||
sds = StringFromList(index, sds, "/")
|
||||
endif
|
||||
endif
|
||||
|
||||
return sds
|
||||
end
|
||||
|
||||
/// 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.
|
||||
@ -617,53 +736,42 @@ end
|
||||
///
|
||||
/// @param scanpath path to the scan group in the HDF5 file, e.g. "/scan 1".
|
||||
///
|
||||
/// @param dataset name of the dataset.
|
||||
/// the name of the loaded wave is a cleaned up version of the dataset name.
|
||||
///
|
||||
/// @param set_scale by 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().
|
||||
/// @arg 1 (default) set the wave scaling.
|
||||
/// @arg 0 do not set the wave scaling.
|
||||
///
|
||||
/// @param pref_datasets semicolon-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.
|
||||
///
|
||||
/// @return name of loaded wave if successful. empty string otherwise.
|
||||
///
|
||||
function /s psh5_load_scan_preview(fileID, scanpath, [set_scale])
|
||||
function /s psh5_load_scan_preview(fileID, scanpath, [set_scale, pref_datasets])
|
||||
variable fileID
|
||||
string scanpath
|
||||
variable set_scale
|
||||
string pref_datasets
|
||||
|
||||
if (ParamIsDefault(set_scale))
|
||||
set_scale = 1
|
||||
endif
|
||||
if (ParamIsDefault(pref_datasets) || (strlen(pref_datasets) == 0))
|
||||
pref_datasets = kPreviewDatasets
|
||||
endif
|
||||
|
||||
dfref saveDF = GetDataFolderDFR()
|
||||
dfref dataDF = saveDF
|
||||
|
||||
string datasets = psh5_list_scan_datasets(fileID, scanpath)
|
||||
string datasetname = ""
|
||||
variable index
|
||||
// todo: this should be generalized
|
||||
if (strsearch(datasets, "ScientaImage", 0) >= 0)
|
||||
datasetname = "ScientaImage"
|
||||
elseif (strsearch(datasets, "ScientaSpectrum", 0) >= 0)
|
||||
datasetname = "ScientaSpectrum"
|
||||
elseif (strsearch(datasets, "ScientaEnergyDistribution", 0) >= 0)
|
||||
datasetname = "ScientaEnergyDistribution"
|
||||
elseif (strsearch(datasets, "ImageEnergyDistribution", 0) >= 0)
|
||||
datasetname = "ImageEnergyDistribution"
|
||||
elseif (strsearch(datasets, "Counts", 0) >= 0)
|
||||
datasetname = "Counts"
|
||||
elseif (strsearch(datasets, "SampleCurrent", 0) >= 0)
|
||||
datasetname = "SampleCurrent"
|
||||
else
|
||||
datasetname = StringFromList(0, datasets)
|
||||
index = ItemsInList(datasetname, "/") - 1
|
||||
datasetname = StringFromList(index, datasetname, "/")
|
||||
endif
|
||||
if (strlen(datasetname) == 0)
|
||||
return ""
|
||||
endif
|
||||
|
||||
string datasetname = select_dataset(datasets, pref_datasets)
|
||||
string datasetpath
|
||||
datasetpath = scanpath + "/" + datasetname
|
||||
datasetpath = ReplaceString("//", datasetpath, "/")
|
||||
|
||||
STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
|
||||
InitHDF5DataInfo(di)
|
||||
variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
|
||||
@ -673,7 +781,7 @@ function /s psh5_load_scan_preview(fileID, scanpath, [set_scale])
|
||||
endif
|
||||
|
||||
string dataname
|
||||
if (di.ndims < 3)
|
||||
if (di.ndims < 2)
|
||||
HDF5LoadData /O /Q /Z fileID, datasetpath
|
||||
dataname = StringFromList(0, S_waveNames)
|
||||
wave /z data = $dataname
|
||||
@ -729,6 +837,153 @@ function /s psh5_load_scan_preview(fileID, scanpath, [set_scale])
|
||||
return dataname
|
||||
end
|
||||
|
||||
/// load a longitudinal section of a scan from an open PShell HDF5 file.
|
||||
///
|
||||
/// the dataset must have three dimensions.
|
||||
///
|
||||
///
|
||||
/// @param fileID ID of open HDF5 file from psh5_open_file().
|
||||
///
|
||||
/// @param scanpath path to the scan group in the HDF5 file, e.g. "/scan 1".
|
||||
///
|
||||
/// @param dim reserved, must be 0.
|
||||
///
|
||||
/// @param set_scale by 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().
|
||||
/// @arg 1 (default) set the wave scaling.
|
||||
/// @arg 0 do not set the wave scaling.
|
||||
///
|
||||
/// @param pref_datasets semicolon-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.
|
||||
///
|
||||
/// @return name of loaded wave if successful. empty string otherwise.
|
||||
///
|
||||
/// @warning EXPERIMENTAL: this function is under development.
|
||||
///
|
||||
function /s psh5_load_scan_section(fileID, scanpath, dim, [set_scale, pref_datasets])
|
||||
variable fileID
|
||||
string scanpath
|
||||
variable dim
|
||||
variable set_scale
|
||||
string pref_datasets
|
||||
|
||||
// select first dimension (future argument)
|
||||
// 0 = first dimension is x axis (energy of scienta image)
|
||||
dim = 0
|
||||
|
||||
if (ParamIsDefault(set_scale))
|
||||
set_scale = 1
|
||||
endif
|
||||
if (ParamIsDefault(pref_datasets) || (strlen(pref_datasets) == 0))
|
||||
pref_datasets = kPreviewDatasets
|
||||
endif
|
||||
|
||||
dfref saveDF = GetDataFolderDFR()
|
||||
dfref dataDF = saveDF
|
||||
|
||||
string datasets = psh5_list_scan_datasets(fileID, scanpath)
|
||||
string datasetname = select_dataset(datasets, pref_datasets)
|
||||
string datasetpath
|
||||
datasetpath = scanpath + "/" + datasetname
|
||||
datasetpath = ReplaceString("//", datasetpath, "/")
|
||||
string dataname = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
|
||||
string destname = dataname[0,29] + num2str(dim)
|
||||
|
||||
STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
|
||||
InitHDF5DataInfo(di)
|
||||
variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
|
||||
if (err != 0)
|
||||
print "error accessing detector/data"
|
||||
return ""
|
||||
elseif (di.ndims != 3)
|
||||
print "error: rank of dataset != 3"
|
||||
return ""
|
||||
endif
|
||||
|
||||
variable idx, idy, idz, idt
|
||||
variable transpose = WhichListItem(dataname, kTransposedDatasets) >= 0
|
||||
if (transpose)
|
||||
idx = 1
|
||||
idy = 0
|
||||
else
|
||||
idx = 0
|
||||
idy = 1
|
||||
endif
|
||||
idz = 2
|
||||
idt = 3
|
||||
|
||||
variable nx, ny, nz
|
||||
nx = di.dims[idx]
|
||||
ny = di.dims[idy]
|
||||
nz = di.dims[idz]
|
||||
|
||||
HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
|
||||
wave slab
|
||||
slab[][%Start] = 0
|
||||
slab[][%Stride] = 1
|
||||
slab[][%Count] = 1
|
||||
slab[][%Block] = 1
|
||||
|
||||
if (dim == 0)
|
||||
slab[idy][%Start] = floor(ny / 2)
|
||||
slab[idx][%Block] = nx
|
||||
make /n=(nx,nz) /o $destname
|
||||
else
|
||||
slab[idx][%Start] = floor(nx / 2)
|
||||
slab[idy][%Block] = ny
|
||||
make /n=(ny,nz) /o $destname
|
||||
endif
|
||||
slab[idz][%Block] = nz
|
||||
wave data = $destname
|
||||
data = 0
|
||||
|
||||
HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
|
||||
if (!v_flag)
|
||||
wave slabdata
|
||||
if (transpose)
|
||||
data += slabdata[0][p][q][0]
|
||||
else
|
||||
data += slabdata[p][0][q][0]
|
||||
endif
|
||||
endif
|
||||
killwaves /z slab, slabdata
|
||||
|
||||
if (set_scale)
|
||||
make /n=(1,1,1) /free dummy
|
||||
ps_set_dimlabels2(dummy, dataname)
|
||||
setdimlabel 0, -1, $GetDimLabel(dummy, dim, -1), data
|
||||
setdimlabel 1, -1, $kScanDimLabel, data
|
||||
|
||||
setdatafolder dataDF
|
||||
string positioners
|
||||
string positioner
|
||||
string positionerpath
|
||||
positioners = psh5_load_scan_meta(fileID, scanpath)
|
||||
wave /t /z ScanWritables
|
||||
if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
|
||||
positioner = ScanWritables[0]
|
||||
if (strlen(positioner) > 0)
|
||||
positionerpath = scanpath + "/" + positioner
|
||||
positionerpath = ReplaceString("//", positionerpath, "/")
|
||||
HDF5LoadData /O /Q /Z fileID, positionerpath
|
||||
endif
|
||||
endif
|
||||
|
||||
setdatafolder dataDF
|
||||
newdatafolder /o/s attr
|
||||
killwaves /a/z
|
||||
psh5_load_scan_attrs(fileID, scanpath, attr_sets=2)
|
||||
setdatafolder dataDF
|
||||
ps_scale_dataset(data)
|
||||
endif
|
||||
|
||||
return destname
|
||||
end
|
||||
|
||||
/// load metadata of a PShell dataset.
|
||||
///
|
||||
/// "metadata" are the HDF5 attributes attached to the scan dataset.
|
||||
@ -830,11 +1085,19 @@ function /s psh5_load_dataset_slabs(fileID, datapath, datasetname, [progress])
|
||||
if (di.ndims < 2)
|
||||
print "error: rank of dataset < 2"
|
||||
return ""
|
||||
elseif (di.ndims < 3)
|
||||
progress = 0
|
||||
endif
|
||||
|
||||
variable idx, idy, idz, idt, izt
|
||||
idx = 1
|
||||
idy = 0
|
||||
variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
|
||||
if (transpose)
|
||||
idx = 1
|
||||
idy = 0
|
||||
else
|
||||
idx = 0
|
||||
idy = 1
|
||||
endif
|
||||
idz = 2
|
||||
idt = 3
|
||||
|
||||
@ -871,7 +1134,11 @@ function /s psh5_load_dataset_slabs(fileID, datapath, datasetname, [progress])
|
||||
slab[idt][%Start] = it
|
||||
HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
|
||||
wave slabdata // 2D, 3D, or 4D with singletons
|
||||
data[][][iz][it] = slabdata[q][p][0][0]
|
||||
if (transpose)
|
||||
data[][][iz][it] = slabdata[q][p][0][0]
|
||||
else
|
||||
data[][][iz][it] = slabdata[p][q][0][0]
|
||||
endif
|
||||
|
||||
// progress window
|
||||
izt += 1
|
||||
@ -955,8 +1222,14 @@ function /s psh5_load_dataset_slab(fileID, datapath, datasetname, dim2start, dim
|
||||
endif
|
||||
|
||||
variable idx, idy, idz, idt
|
||||
idx = 1
|
||||
idy = 0
|
||||
variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
|
||||
if (transpose)
|
||||
idx = 1
|
||||
idy = 0
|
||||
else
|
||||
idx = 0
|
||||
idy = 1
|
||||
endif
|
||||
idz = 2
|
||||
idt = 3
|
||||
|
||||
@ -987,7 +1260,11 @@ function /s psh5_load_dataset_slab(fileID, datapath, datasetname, dim2start, dim
|
||||
HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
|
||||
if (!v_flag)
|
||||
wave slabdata
|
||||
data += slabdata[q][p][0][0]
|
||||
if (transpose)
|
||||
data += slabdata[q][p][0][0]
|
||||
else
|
||||
data += slabdata[p][q][0][0]
|
||||
endif
|
||||
navg += 1
|
||||
endif
|
||||
endfor
|
||||
@ -1010,42 +1287,81 @@ end
|
||||
///
|
||||
/// dimension labels are required by scaling functions.
|
||||
///
|
||||
/// @param data data wave as loaded from PShell file
|
||||
///
|
||||
/// @return @arg 0 all labels set successfully.
|
||||
/// @arg 1 unidentified data source.
|
||||
/// @arg 2 wave does not contain data.
|
||||
///
|
||||
function ps_set_dimlabels(data)
|
||||
wave data
|
||||
|
||||
string name = NameOfWave(data)
|
||||
ps_set_dimlabels2(data, NameOfWave(data))
|
||||
end
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// @param data data wave as loaded from PShell file.
|
||||
///
|
||||
/// @param name original name of the dataset in the PShell file.
|
||||
///
|
||||
/// @return @arg 0 all labels set successfully.
|
||||
/// @arg 1 unidentified data source.
|
||||
/// @arg 2 wave does not contain data.
|
||||
///
|
||||
function ps_set_dimlabels2(data, name)
|
||||
wave data
|
||||
string name
|
||||
|
||||
// intrinsic dimensions
|
||||
strswitch(name)
|
||||
case "ScientaImage":
|
||||
setdimlabel 0, -1, $kEnergyDimLabel, data
|
||||
setdimlabel 1, -1, $kAngleDimLabel, data
|
||||
if (WaveDims(data) >= 3)
|
||||
setdimlabel 2, -1, $kScanDimLabel, data
|
||||
endif
|
||||
break
|
||||
case "ImageAngleDistribution":
|
||||
case "ScientaAngleDistribution":
|
||||
if (WaveDims(data) >= 2)
|
||||
setdimlabel 0, -1, $kScanDimLabel, data
|
||||
setdimlabel 1, -1, $kAngleDimLabel, data
|
||||
else
|
||||
setdimlabel 0, -1, $kAngleDimLabel, data
|
||||
endif
|
||||
break
|
||||
case "ScientaSpectrum":
|
||||
case "ImageEnergyDistribution":
|
||||
case "ScientaEnergyDistribution":
|
||||
if (WaveDims(data) >= 2)
|
||||
setdimlabel 0, -1, $kScanDimLabel, data
|
||||
setdimlabel 1, -1, $kEnergyDimLabel, data
|
||||
else
|
||||
variable dummy
|
||||
try
|
||||
// intrinsic dimensions
|
||||
strswitch(name)
|
||||
case "ScientaImage":
|
||||
setdimlabel 0, -1, $kEnergyDimLabel, data
|
||||
endif
|
||||
break
|
||||
default:
|
||||
setdimlabel 0, -1, $kScanDimLabel, data
|
||||
endswitch
|
||||
setdimlabel 1, -1, $kAngleDimLabel, data
|
||||
if (WaveDims(data) >= 3)
|
||||
setdimlabel 2, -1, $kScanDimLabel, data
|
||||
endif
|
||||
AbortOnRTE
|
||||
break
|
||||
case "ImageAngleDistribution":
|
||||
case "ScientaAngleDistribution":
|
||||
if (WaveDims(data) >= 2)
|
||||
setdimlabel 0, -1, $kScanDimLabel, data
|
||||
setdimlabel 1, -1, $kAngleDimLabel, data
|
||||
else
|
||||
setdimlabel 0, -1, $kAngleDimLabel, data
|
||||
endif
|
||||
AbortOnRTE
|
||||
break
|
||||
case "ScientaSpectrum":
|
||||
case "ImageEnergyDistribution":
|
||||
case "ScientaEnergyDistribution":
|
||||
if (WaveDims(data) >= 2)
|
||||
setdimlabel 0, -1, $kScanDimLabel, data
|
||||
setdimlabel 1, -1, $kEnergyDimLabel, data
|
||||
else
|
||||
setdimlabel 0, -1, $kEnergyDimLabel, data
|
||||
endif
|
||||
AbortOnRTE
|
||||
break
|
||||
default:
|
||||
if (WaveDims(data) == 1)
|
||||
setdimlabel 0, -1, $kScanDimLabel, data
|
||||
AbortOnRTE
|
||||
else
|
||||
return 1
|
||||
endif
|
||||
endswitch
|
||||
catch
|
||||
dummy = GetRTError(1)
|
||||
return 2
|
||||
endtry
|
||||
return 0
|
||||
end
|
||||
|
||||
/// set the dimension scales of loaded PShell Scienta datasets according to attributes.
|
||||
@ -1219,7 +1535,7 @@ function ps_detect_scale(ax, lo, hi, un)
|
||||
if (!WaveExists(scanner))
|
||||
wave /z /SDFR=attrDF scanner = $ScanWritables[0]
|
||||
endif
|
||||
if (WaveExists(scanner))
|
||||
if (WaveExists(scanner) && (numpnts(scanner) >= 1))
|
||||
lo[%$kScanDimLabel] = scanner[0]
|
||||
hi[%$kScanDimLabel] = scanner[numpnts(scanner)-1]
|
||||
ax[%$kScanDimLabel] = NameOfWave(scanner)
|
||||
@ -1362,7 +1678,9 @@ function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, r
|
||||
string folder
|
||||
|
||||
sg = StringFromList(ig, s_scanpaths)
|
||||
folder = CleanupName(ReplaceString("/", sg, ""), 0)
|
||||
folder = ReplaceString("/", sg, "")
|
||||
folder = ReplaceString(" ", folder, "")
|
||||
folder = CleanupName(folder, 0)
|
||||
setdatafolder fileDF
|
||||
newdatafolder /s /o $folder
|
||||
dfref dataDF = GetDataFolderDFR()
|
||||
@ -1464,11 +1782,19 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
print "error: rank of dataset < 2"
|
||||
result = -2
|
||||
return wavenames
|
||||
elseif (di.ndims < 3)
|
||||
progress = 0
|
||||
endif
|
||||
|
||||
variable idx, idy, idz, idt
|
||||
idx = 1
|
||||
idy = 0
|
||||
variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
|
||||
if (transpose)
|
||||
idx = 1
|
||||
idy = 0
|
||||
else
|
||||
idx = 0
|
||||
idy = 1
|
||||
endif
|
||||
idz = 2
|
||||
idt = 3
|
||||
|
||||
|
Reference in New Issue
Block a user