new features: data reduction, angle scan panel
- new data reduction interface for more efficient multi-peak fitting. the new interface breaks compatibility with pre-2.0 data reduction functions. user-defined functions must be adapted to the new interface. - new angle scan processing panel for interactive data analysis.
This commit is contained in:
1413
pearl/pearl-anglescan-panel.ipf
Normal file
1413
pearl/pearl-anglescan-panel.ipf
Normal file
File diff suppressed because it is too large
Load Diff
@ -164,10 +164,10 @@ end
|
||||
///
|
||||
/// @param[in] smooth_method smoothing method
|
||||
/// @arg 0 none
|
||||
/// @arg 1 (default) binomial, see Igor's Smooth operation
|
||||
/// @arg 1 binomial, see Igor's Smooth operation
|
||||
/// @arg 2 boxcar, see Igor's Smooth operation
|
||||
/// @arg 3 scienta_ang_transm() function fit
|
||||
/// @arg 4 LOESS smoothing, see Igor's Loess operation
|
||||
/// @arg 4 (default) LOESS smoothing, see Igor's Loess operation
|
||||
///
|
||||
/// @param[in] smooth_factor num parameter of Igor's Smooth operation.
|
||||
/// the default value depends on smooth_method.
|
||||
@ -189,7 +189,7 @@ function normalize_strip_x(strip, [smooth_method, smooth_factor, check])
|
||||
variable check
|
||||
|
||||
if (ParamIsDefault(smooth_method))
|
||||
smooth_method = 1
|
||||
smooth_method = 4
|
||||
endif
|
||||
if (ParamIsDefault(smooth_factor))
|
||||
switch(smooth_method)
|
||||
@ -419,6 +419,89 @@ function normalize_strip_theta(strip, theta, [theta_offset, smooth_method, smoot
|
||||
endif
|
||||
end
|
||||
|
||||
/// divide the strip by a smooth polar-azimuthal distribution.
|
||||
///
|
||||
/// this is a simple way to remove the polar angle dependence.
|
||||
/// in contrast to @ref normalize_strip_theta this function also removes a smooth variation over azimuthal angles.
|
||||
///
|
||||
/// the strip is normalized in place, previous data is overwritten.
|
||||
///
|
||||
/// @warning experimental. this function is under development.
|
||||
///
|
||||
/// @param[in,out] strip 2D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan
|
||||
/// @param[in] theta polar manipulator angle, 0 = normal emission, 90 = grazing emission
|
||||
/// @param[in] phi azimuthal manipulator angle.
|
||||
/// @param[in] theta_offset
|
||||
/// @param[in] smooth_method smoothing method
|
||||
/// @arg 0 none
|
||||
/// @arg 4 (default) Loess, see Igor's Loess operation
|
||||
///
|
||||
/// @param[in] smooth_factor smoothing parameter, depends on smooth_method
|
||||
/// @arg loess: see Igor's Loess operation, 0 <= smooth_factor <= 1, default 0.5
|
||||
///
|
||||
/// @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_thetaphi(strip, theta, phi, [theta_offset, smooth_method, smooth_factor, check])
|
||||
wave strip
|
||||
wave theta
|
||||
wave phi
|
||||
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
|
||||
|
||||
// average over analyser angles
|
||||
wave dist = ad_profile_y(strip, -inf, inf, "")
|
||||
|
||||
// smooth distribution function
|
||||
duplicate /free dist, dist_smoo
|
||||
duplicate /free theta, theta_int
|
||||
theta_int = theta - theta_offset
|
||||
setscale /p x theta_int[0], theta_int[1] - theta_int[0], waveunits(theta,-1), dist, dist_smoo
|
||||
variable nx = dimsize(strip, 0)
|
||||
variable ix
|
||||
|
||||
switch(smooth_method)
|
||||
case 4:
|
||||
loess /dest=dist_smoo /smth=(smooth_factor) srcWave=dist, factors={theta_int, phi}
|
||||
break
|
||||
default:
|
||||
abort "smooth method not supported"
|
||||
endswitch
|
||||
|
||||
// divide
|
||||
if (check != 2)
|
||||
strip /= dist_smoo[q]
|
||||
endif
|
||||
|
||||
// check
|
||||
if (check)
|
||||
duplicate /o dist, check_dist
|
||||
duplicate /o dist_smoo, check_smoo
|
||||
setscale /p x dimoffset(dist,0), dimdelta(dist,0), waveunits(dist,0), check_dist, check_smoo
|
||||
endif
|
||||
end
|
||||
|
||||
/// divide the strip by a two-dimensional normalization function.
|
||||
///
|
||||
/// @warning experimental. this function is under development.
|
||||
@ -1479,11 +1562,13 @@ end
|
||||
/// @param nickname name prefix of holo waves.
|
||||
/// may be empty.
|
||||
///
|
||||
/// @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
|
||||
///
|
||||
/// @param graphtype type of graph
|
||||
/// @arg 1 (pol, az) trace in Igor "New Polar" (default).
|
||||
|
@ -436,7 +436,7 @@ static function setup_detector()
|
||||
setdatafolder $(package_path)
|
||||
|
||||
make /n=31 /o detector_angle, detector_pol, detector_az, detector_rad
|
||||
setscale /i x -30, 30, "°", detector_angle, detector_pol, detector_az, detector_rad
|
||||
setscale /i x -30, 30, "<EFBFBD>", detector_angle, detector_pol, detector_az, detector_rad
|
||||
detector_angle = x
|
||||
|
||||
setdatafolder saveDF
|
||||
@ -468,9 +468,14 @@ static function add_image_data(image, theta, tilt, phi)
|
||||
svar red_params = reduction_params
|
||||
funcref adh5_default_reduction red_func = $red_func_name
|
||||
variable nx = dimsize(image, 0)
|
||||
make /n=(nx) /free profile1, profile2
|
||||
string loc_params = red_params
|
||||
red_func(image, profile1, profile2, loc_params)
|
||||
wave /wave red_results = red_func(image, loc_params)
|
||||
if (numpnts(red_results) < 1)
|
||||
setdatafolder saveDF
|
||||
return 0
|
||||
endif
|
||||
|
||||
wave profile1 = red_results[0]
|
||||
nx = numpnts(profile1)
|
||||
|
||||
// write the result to the buffer
|
||||
@ -573,7 +578,7 @@ static function update_detector(theta, tilt, phi, range)
|
||||
//m_phi *= -1 // checked 140702
|
||||
|
||||
wave detector_angle, detector_pol, detector_az, detector_rad
|
||||
setscale /i x -range/2, +range/2, "°", detector_angle
|
||||
setscale /i x -range/2, +range/2, "<EFBFBD>", detector_angle
|
||||
detector_angle = x
|
||||
|
||||
convert_angles_ttpa2polar(m_theta, m_tilt, m_phi, detector_angle, detector_pol, detector_az)
|
||||
|
@ -1,11 +1,10 @@
|
||||
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
|
||||
#pragma IgorVersion = 6.2
|
||||
#pragma ModuleName = PearlAreaImport
|
||||
#pragma version = 1.06
|
||||
#include <HDF5 Browser>
|
||||
#include "pearl-gui-tools"
|
||||
|
||||
// copyright (c) 2013-16 Paul Scherrer Institut
|
||||
// copyright (c) 2013-18 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.
|
||||
@ -23,6 +22,14 @@
|
||||
/// as of Igor 6.3, Igor can open datasets of up to rank 4.
|
||||
/// i.e. the extra dimension Y of the file plugin cannot be used.
|
||||
/// the extra dimensions N and X are supported.
|
||||
///
|
||||
/// @author matthias muntwiler, matthias.muntwiler@psi.ch
|
||||
///
|
||||
/// @copyright 2013-18 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
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
/// @namespace PearlAreaImport
|
||||
/// @brief HDF5 file import from EPICS area detectors
|
||||
@ -1031,7 +1038,7 @@ end
|
||||
/// it may thus include functions which are not suitable as reduction functions.
|
||||
///
|
||||
function /s adh5_list_reduction_funcs()
|
||||
string all_funcs = FunctionList("*", ";", "KIND:6,NPARAMS:4,VALTYPE:1")
|
||||
string all_funcs = FunctionList("*", ";", "KIND:6,NPARAMS:2,VALTYPE:8")
|
||||
string result = ""
|
||||
|
||||
variable ii
|
||||
@ -1045,16 +1052,14 @@ function /s adh5_list_reduction_funcs()
|
||||
for (ii = 0; ii < nn; ii += 1)
|
||||
funcname = StringFromList(ii, all_funcs, ";")
|
||||
info = FunctionInfo(funcname)
|
||||
accept = (NumberByKey("RETURNTYPE", info, ":", ";") == 0x0004)
|
||||
accept = (NumberByKey("RETURNTYPE", info, ":", ";") == 0x4000)
|
||||
accept = accept && (cmpstr(StringByKey("THREADSAFE", info, ":", ";"), "yes") == 0)
|
||||
accept = accept && (NumberByKey("N_PARAMS", info, ":", ";") == 4)
|
||||
accept = accept && (NumberByKey("N_PARAMS", info, ":", ";") == 2)
|
||||
accept = accept && (NumberByKey("N_OPT_PARAMS", info, ":", ";") == 0)
|
||||
if (accept)
|
||||
// 3 numeric waves and one pass-by-reference string
|
||||
// one numeric wave and one pass-by-reference string
|
||||
accept = accept && (NumberByKey("PARAM_0_TYPE", info, ":", ";") == 0x4002)
|
||||
accept = accept && (NumberByKey("PARAM_1_TYPE", info, ":", ";") == 0x4002)
|
||||
accept = accept && (NumberByKey("PARAM_2_TYPE", info, ":", ";") == 0x4002)
|
||||
accept = accept && (NumberByKey("PARAM_3_TYPE", info, ":", ";") == 0x3000)
|
||||
accept = accept && (NumberByKey("PARAM_1_TYPE", info, ":", ";") == 0x3000)
|
||||
endif
|
||||
if (accept)
|
||||
result = AddListItem(funcname, result, ";")
|
||||
@ -1067,9 +1072,18 @@ end
|
||||
|
||||
/// function prototype for adh5_load_reduced_detector
|
||||
///
|
||||
/// derived functions reduce a two-dimensional dataset to a one-dimensional dataset,
|
||||
/// e.g. by ROI-integration, curve fitting, etc.
|
||||
// the resulting wave must have the same size as either dimension of the source image.
|
||||
/// this is a prototype of custom functions that convert (reduce) a two-dimensional detector image
|
||||
/// into one or more one-dimensional waves.
|
||||
/// data processing can be tuned with a set of parameters.
|
||||
///
|
||||
/// reduction functions have a fixed signature (function arguments) so that the file import functions
|
||||
/// can call them efficiently on a series of detector images.
|
||||
/// pearl procedures comes with a number of pre-defined reduction functions
|
||||
/// but you may as well implement your own functions.
|
||||
/// if you write your own function, you must use the same declaration and arguments
|
||||
/// as this function except for the function name.
|
||||
/// you can do many things in a reduction function,
|
||||
/// e.g. integration over a region of interest, curve fitting, etc.
|
||||
///
|
||||
/// each destination wave is a one-dimensional intensity distribution.
|
||||
/// the function must redimension each of these waves to one of the image dimensions
|
||||
@ -1077,32 +1091,38 @@ end
|
||||
/// this function will also copy the scale information and dimension labels,
|
||||
/// which is important for the proper scaling of the result.
|
||||
///
|
||||
/// the meaning of the data in dest1 and dest2 is up to the particular function,
|
||||
/// the meaning of the data in the result waves is up to the particular function,
|
||||
/// e.g. dest1 could hold the mean value and dest2 the one-sigma error,
|
||||
/// or dest1 could hold the X-profile, and dest2 the Y-profile.
|
||||
///
|
||||
/// @param source source wave
|
||||
/// two-dimensional intensity distribution (image)
|
||||
/// @param dest1, dest2 destination waves
|
||||
/// @param param string with optional parameters, shared between calls.
|
||||
/// @param source source wave.
|
||||
/// two-dimensional intensity distribution (image).
|
||||
/// the scales are carried over to the result waves.
|
||||
///
|
||||
/// @param param string with optional parameters, shared between calls.
|
||||
/// this is a pass-by-reference argument,
|
||||
/// the function may modify the string
|
||||
/// the function may modify the string.
|
||||
///
|
||||
/// @return zero if successful, non-zero if an error occurs.
|
||||
/// @return a free wave containing references of the result waves.
|
||||
/// the result waves should as well be free waves.
|
||||
/// if an error occurred, the reference wave is empty.
|
||||
///
|
||||
threadsafe function adh5_default_reduction(source, dest1, dest2, param)
|
||||
threadsafe function /wave adh5_default_reduction(source, param)
|
||||
wave source
|
||||
wave dest1, dest2
|
||||
string ¶m
|
||||
|
||||
// demo code
|
||||
// integrate along the dimensions
|
||||
// integrate along the dimensions
|
||||
make /n=0 /free dest1, dest2
|
||||
adh5_setup_profile(source, dest1, 0)
|
||||
ad_profile_x_w(source, 0, -1, dest1)
|
||||
adh5_setup_profile(source, dest2, 1)
|
||||
ad_profile_y_w(source, 0, -1, dest2)
|
||||
|
||||
return 0
|
||||
make /n=2 /free /wave results
|
||||
results[0] = dest1
|
||||
results[1] = dest2
|
||||
return results
|
||||
end
|
||||
|
||||
/// set up a one-dimensional wave for a line profile based on a 2D original wave.
|
||||
@ -1123,20 +1143,66 @@ end
|
||||
|
||||
/// wrapper function for testing reduction functions from the command line.
|
||||
///
|
||||
/// Igor does not allow global variables as pass-by-reference parameter for reduction_param.
|
||||
/// reduction functions cannot be used on the command line because they require
|
||||
/// a pass-by-reference argument and return free waves.
|
||||
/// this function expects the reduction parameters in a normal string
|
||||
/// and copies the results into the current data folder.
|
||||
/// the prefix of the result names can be specified.
|
||||
///
|
||||
function /s adh5_test_reduction_func(source, dest1, dest2, reduction_func, reduction_param)
|
||||
/// @param source source wave.
|
||||
/// two-dimensional intensity distribution (image).
|
||||
/// the scales are carried over to the result waves.
|
||||
///
|
||||
/// @param reduction_func name of the reduction function to apply to the source data.
|
||||
///
|
||||
/// @param reduction_param string with reduction parameters as required by the specific reduction function.
|
||||
///
|
||||
/// @param result_prefix name prefix of result waves.
|
||||
/// a numeric index is appended to distinguish the results.
|
||||
/// the index starts at 1. existing waves are overwritten.
|
||||
///
|
||||
/// @return a copy of the reduction_param string, possibly modified by the reduction function.
|
||||
///
|
||||
function /s adh5_test_reduction_func(source, reduction_func, reduction_param, result_prefix)
|
||||
wave source
|
||||
wave dest1
|
||||
wave dest2
|
||||
funcref adh5_default_reduction reduction_func
|
||||
string reduction_param
|
||||
string result_prefix
|
||||
|
||||
reduction_func(source, dest1, dest2, reduction_param)
|
||||
wave /wave results = reduction_func(source, reduction_param)
|
||||
adh5_get_result_waves(results, result_prefix, 1)
|
||||
|
||||
return reduction_param
|
||||
end
|
||||
|
||||
/// copy waves from wave reference wave into current data folder
|
||||
///
|
||||
/// this function copies waves that are referenced in a wave reference wave into the current data folder.
|
||||
/// the destination waves get new names consisting of a prefix and a numeric index.
|
||||
/// the index is the array index of the wave in results plus a chosen offset.
|
||||
///
|
||||
/// @param results a wave reference wave pointing to result waves from data reduction.
|
||||
/// the waves can be free or regular waves.
|
||||
/// results can be a free or regular wave.
|
||||
///
|
||||
/// @param result_prefix name prefix of the copied waves.
|
||||
///
|
||||
/// @param start_index start index (offset) of the copied waves.
|
||||
///
|
||||
threadsafe function adh5_get_result_waves(results, result_prefix, start_index)
|
||||
wave /wave results
|
||||
string result_prefix
|
||||
variable start_index
|
||||
|
||||
variable nw = numpnts(results)
|
||||
variable iw
|
||||
string sw
|
||||
for (iw = 0; iw < nw; iw += 1)
|
||||
sw = result_prefix + num2str(iw + start_index)
|
||||
duplicate /o results[iw], $sw
|
||||
endfor
|
||||
end
|
||||
|
||||
/// load a reduced detector dataset from the open HDF5 file.
|
||||
///
|
||||
/// the function loads the dataset image by image using the hyperslab option
|
||||
@ -1266,6 +1332,10 @@ function adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduct
|
||||
|
||||
variable iz, it
|
||||
string dfname
|
||||
variable iw, nw
|
||||
string sw
|
||||
make /n=0 /free /wave result_waves
|
||||
|
||||
izt = 0
|
||||
for (iz = 0; iz < nz; iz += 1)
|
||||
for (it = 0; it < nt; it += 1)
|
||||
@ -1287,11 +1357,11 @@ function adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduct
|
||||
ThreadGroupPutDF threadGroupID, :
|
||||
else
|
||||
processing_folders[izt] = GetDataFolderDFR()
|
||||
make /n=1/d profile1, profile2
|
||||
wave slabdata
|
||||
variable /g func_result
|
||||
func_result = reduce_slab_image(slabdata, image, profile1, profile2, reduction_func, func_param)
|
||||
WaveClear slabdata, image, profile1, profile2
|
||||
wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
|
||||
variable /g func_result = numpnts(reduced_waves)
|
||||
adh5_get_result_waves(reduced_waves, "redw_", 0)
|
||||
WaveClear slabdata, image, reduced_waves
|
||||
setdatafolder ::
|
||||
endif
|
||||
|
||||
@ -1343,26 +1413,32 @@ function adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduct
|
||||
nvar rr = dfr:r_index
|
||||
nvar ss = dfr:s_index
|
||||
nvar func_result = dfr:func_result
|
||||
wave profile1 = dfr:profile1
|
||||
wave profile2 = dfr:profile2
|
||||
|
||||
if (func_result == 0)
|
||||
if (izt == 0)
|
||||
make /n=(dimsize(profile1, 0), nz, nt)/d/o data1
|
||||
make /n=(dimsize(profile2, 0), nz, nt)/d/o data2
|
||||
setdimlabel 0, -1, $getdimlabel(profile1, 0, -1), data1
|
||||
setdimlabel 0, -1, $getdimlabel(profile2, 0, -1), data2
|
||||
setscale /p x dimoffset(profile1, 0), dimdelta(profile1, 0), waveunits(profile1, 0), data1
|
||||
setscale /p x dimoffset(profile2, 0), dimdelta(profile2, 0), waveunits(profile2, 0), data2
|
||||
setscale d 0, 0, waveunits(profile1, -1), data1
|
||||
setscale d 0, 0, waveunits(profile2, -1), data2
|
||||
endif
|
||||
data1[][rr][ss] = profile1[p]
|
||||
data2[][rr][ss] = profile2[p]
|
||||
else
|
||||
if (func_result < 1)
|
||||
result = -3 // dimension reduction error
|
||||
break
|
||||
endif
|
||||
|
||||
if (numpnts(result_waves) == 0)
|
||||
redimension /n=(func_result) result_waves
|
||||
for (iw = 0; iw < func_result; iw += 1)
|
||||
sw = "redw_" + num2str(iw)
|
||||
wave profile = dfr:$sw
|
||||
sw = "ReducedData" + num2str(iw+1)
|
||||
make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
|
||||
wave data = $sw
|
||||
setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
|
||||
setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
|
||||
setscale d 0, 0, waveunits(profile, -1), data
|
||||
result_waves[iw] = data
|
||||
endfor
|
||||
endif
|
||||
for (iw = 0; iw < func_result; iw += 1)
|
||||
sw = "redw_" + num2str(iw)
|
||||
wave profile = dfr:$sw
|
||||
wave data = result_waves[iw]
|
||||
data[][rr][ss] = profile[p]
|
||||
endfor
|
||||
endfor
|
||||
|
||||
if (nthreads > 0)
|
||||
@ -1377,20 +1453,19 @@ function adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduct
|
||||
endif
|
||||
|
||||
if (result == 0)
|
||||
if (nz == 1)
|
||||
redimension /n=(dimsize(data1,0)) data1
|
||||
redimension /n=(dimsize(data2,0)) data2
|
||||
elseif (nt == 1)
|
||||
redimension /n=(dimsize(data1,0),nz) data1
|
||||
redimension /n=(dimsize(data2,0),nz) data2
|
||||
setdimlabel 1, -1, AD_DimN, data1
|
||||
setdimlabel 1, -1, AD_DimN, data2
|
||||
else
|
||||
setdimlabel 1, -1, AD_DimN, data1
|
||||
setdimlabel 1, -1, AD_DimN, data2
|
||||
setdimlabel 2, -1, AD_DimX, data1
|
||||
setdimlabel 2, -1, AD_DimX, data2
|
||||
endif
|
||||
nw = numpnts(result_waves)
|
||||
for (iw = 0; iw < nw; iw += 1)
|
||||
wave data = result_waves[iw]
|
||||
if (nz == 1)
|
||||
redimension /n=(dimsize(data, 0)) data
|
||||
elseif (nt == 1)
|
||||
redimension /n=(dimsize(data, 0),nz) data
|
||||
setdimlabel 1, -1, AD_DimN, data
|
||||
else
|
||||
setdimlabel 1, -1, AD_DimN, data
|
||||
setdimlabel 2, -1, AD_DimX, data
|
||||
endif
|
||||
endfor
|
||||
endif
|
||||
if (progress)
|
||||
kill_progress_panel()
|
||||
@ -1426,14 +1501,14 @@ threadsafe static function reduce_slab_worker(reduction_func)
|
||||
|
||||
// do the work
|
||||
newdatafolder /s outDF
|
||||
make /n=1/d profile1, profile2
|
||||
variable /g r_index = rr
|
||||
variable /g s_index = ss
|
||||
variable /g func_result
|
||||
func_result = reduce_slab_image(slabdata, image, profile1, profile2, reduction_func, func_param)
|
||||
wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
|
||||
variable /g func_result = numpnts(reduced_waves)
|
||||
|
||||
// send output to queue and clean up
|
||||
WaveClear slabdata, image, profile1, profile2
|
||||
adh5_get_result_waves(reduced_waves, "redw_", 0)
|
||||
WaveClear slabdata, image, reduced_waves
|
||||
ThreadGroupPutDF 0, :
|
||||
KillDataFolder dfr
|
||||
while (1)
|
||||
@ -1441,11 +1516,9 @@ threadsafe static function reduce_slab_worker(reduction_func)
|
||||
return 0
|
||||
end
|
||||
|
||||
threadsafe static function reduce_slab_image(slabdata, image, profile1, profile2, reduction_func, reduction_param)
|
||||
threadsafe static function /wave reduce_slab_image(slabdata, image, reduction_func, reduction_param)
|
||||
wave slabdata
|
||||
wave image
|
||||
wave profile1
|
||||
wave profile2
|
||||
funcref adh5_default_reduction reduction_func
|
||||
string reduction_param
|
||||
|
||||
@ -1461,7 +1534,7 @@ threadsafe static function reduce_slab_image(slabdata, image, profile1, profile2
|
||||
break
|
||||
endswitch
|
||||
|
||||
return reduction_func(image, profile1, profile2, reduction_param)
|
||||
return reduction_func(image, reduction_param)
|
||||
end
|
||||
|
||||
/// load an NDAttributes group from an open HDF5 file into the current data folder.
|
||||
@ -1667,12 +1740,12 @@ function adh5_scale_scienta(data)
|
||||
case 1: // Angular45
|
||||
ALow = -45/2
|
||||
AHigh = +45/2
|
||||
AUnit = "°"
|
||||
AUnit = "<EFBFBD>"
|
||||
break
|
||||
case 2: // Angular60
|
||||
ALow = -60/2
|
||||
AHigh = +60/2
|
||||
AUnit = "°"
|
||||
AUnit = "<EFBFBD>"
|
||||
break
|
||||
endswitch
|
||||
endif
|
||||
|
@ -1,13 +1,14 @@
|
||||
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
|
||||
#pragma IgorVersion = 6.1
|
||||
#pragma ModuleName = PearlArpes
|
||||
#pragma version = 1.04
|
||||
#pragma version = 1.05
|
||||
#include "pearl-area-display" // 2D and 3D data visualization
|
||||
#include "pearl-area-profiles" // data processing for multi-dimensional datasets
|
||||
#include "pearl-area-import" // import data files generated by area detector software
|
||||
#include "pearl-pshell-import"
|
||||
#include "pearl-data-explorer" // preview and import panel for PEARL data
|
||||
#include "pearl-anglescan-process"
|
||||
#include "pearl-anglescan-process" // angle scan (XPD) processing functions
|
||||
#include "pearl-anglescan-panel" // panel interface to angle scan processing
|
||||
#include "pearl-anglescan-tracker" // live preview of hemispherical angle scan
|
||||
#include "pearl-scienta-preprocess" // pre-processing functions for Scienta detector images
|
||||
#include "pearl-elog"
|
||||
@ -40,7 +41,7 @@
|
||||
///
|
||||
/// @author matthias muntwiler, matthias.muntwiler@psi.ch
|
||||
///
|
||||
/// @copyright 2012-15 Paul Scherrer Institut @n
|
||||
/// @copyright 2012-18 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
|
||||
@ -66,6 +67,7 @@
|
||||
/// * pearl-data-explorer.ipf
|
||||
/// * pearl-scienta-preprocess.ipf
|
||||
/// * pearl-anglescan-process.ipf
|
||||
/// * pearl-anglescan-panel.ipf
|
||||
/// * pearl-anglescan-tracker.ipf
|
||||
/// * pearl-elog.ipf
|
||||
///
|
||||
|
@ -1,32 +1,148 @@
|
||||
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
|
||||
#pragma IgorVersion = 6.2
|
||||
#pragma ModuleName = PearlFitFuncs
|
||||
#pragma version = 1.01
|
||||
#include "mm-physconst", version >= 1.05
|
||||
#pragma version = 1.02
|
||||
#include "mm-physconst"
|
||||
|
||||
// various fit functions for photoelectron spectroscopy
|
||||
/// @file
|
||||
/// @brief various fit functions for photoelectron spectroscopy.
|
||||
/// @ingroup ArpesPackage
|
||||
///
|
||||
/// this procedure contains various functions for curve fitting.
|
||||
///
|
||||
/// @author matthias muntwiler, matthias.muntwiler@psi.ch
|
||||
///
|
||||
/// @copyright 2013-18 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
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
// $Id$
|
||||
// author: matthias.muntwiler@psi.ch
|
||||
// Copyright (c) 2013-14 Paul Scherrer Institut
|
||||
/// @namespace PearlFitFuncs
|
||||
/// @brief various fit functions for photoelectron spectroscopy.
|
||||
///
|
||||
/// PearlFitFuncs is declared in @ref pearl-fitfuncs.ipf.
|
||||
|
||||
// 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
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Doniach-Sunjic fit functions
|
||||
// Gaussian shapes
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/// multiple gaussian peaks on a linear background fit function.
|
||||
///
|
||||
/// @note FWHM = width * 2 * sqrt(ln(2)) = width * 1.665
|
||||
///
|
||||
/// @param w shape parameters.
|
||||
/// the length of the wave defines the number of peaks.
|
||||
/// @arg w[0] = constant coefficient of background
|
||||
/// @arg w[1] = linear coefficient of background
|
||||
/// @arg w[2 + (i-1) * 3] = amplitude of peak i
|
||||
/// @arg w[3 + (i-1) * 3] = position of peak i
|
||||
/// @arg w[4 + (i-1) * 3] = width of peak i (see note)
|
||||
/// @param x independent variable
|
||||
///
|
||||
threadsafe function MultiGaussLinBG(w,x) : FitFunc
|
||||
wave w
|
||||
variable x
|
||||
|
||||
variable np = numpnts(w)
|
||||
variable ip
|
||||
|
||||
variable v = w[0] + x * w[1]
|
||||
for (ip = 2; ip < np; ip += 3)
|
||||
v += w[ip] * exp( -( (x - w[ip+1]) / w[ip+2] )^2 )
|
||||
endfor
|
||||
|
||||
return v
|
||||
end
|
||||
|
||||
/// multiple gaussian peaks on a linear background fit function (all at once).
|
||||
///
|
||||
/// this is the all-at-once version of @ref MultiGaussLinBG.
|
||||
/// it runs about 15% faster compared to the point-by-point function
|
||||
/// (measured on a 200 point spectrum with 3 peaks).
|
||||
///
|
||||
/// @note FWHM = width * 2 * sqrt(ln(2)) = width * 1.665
|
||||
///
|
||||
/// @param pw shape parameters.
|
||||
/// the length of the wave defines the number of peaks.
|
||||
/// @arg pw[0] = constant coefficient of background
|
||||
/// @arg pw[1] = linear coefficient of background
|
||||
/// @arg pw[2 + (i-1) * 3] = amplitude of peak i
|
||||
/// @arg pw[3 + (i-1) * 3] = position of peak i
|
||||
/// @arg pw[4 + (i-1) * 3] = width of peak i (see note)
|
||||
///
|
||||
/// @param yw y (dependent) values.
|
||||
///
|
||||
/// @param xw x (independent) independent values.
|
||||
///
|
||||
threadsafe function MultiGaussLinBG_AO(pw, yw, xw) : FitFunc
|
||||
wave pw
|
||||
wave yw
|
||||
wave xw
|
||||
|
||||
variable np = numpnts(pw)
|
||||
variable ip
|
||||
|
||||
yw = pw[0] + xw[p] * pw[1]
|
||||
for (ip = 2; ip < np; ip += 3)
|
||||
yw += pw[ip] * exp( -( (xw[p] - pw[ip+1]) / pw[ip+2] )^2 )
|
||||
endfor
|
||||
end
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Voigt shapes
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/// multiple voigt peaks on a linear background fit function.
|
||||
///
|
||||
///
|
||||
/// @param w shape parameters.
|
||||
/// the length of the wave defines the number of peaks.
|
||||
/// @arg w[0] = constant coefficient of background
|
||||
/// @arg w[1] = linear coefficient of background
|
||||
/// @arg w[2 + (i-1) * 4] = amplitude of peak i
|
||||
/// @arg w[3 + (i-1) * 4] = position of peak i
|
||||
/// @arg w[4 + (i-1) * 4] = width of peak i
|
||||
/// @arg w[5 + (i-1) * 4] = shape of peak i
|
||||
/// @param x independent variable
|
||||
///
|
||||
function MultiVoigtLinBG(w,x) : FitFunc
|
||||
wave w
|
||||
variable x
|
||||
|
||||
variable np = numpnts(w)
|
||||
variable ip
|
||||
|
||||
variable v = w[0] + x * w[1]
|
||||
for (ip = 2; ip < np; ip += 4)
|
||||
v += w[ip] * VoigtFunc((x - w[ip+1]) / w[ip+2], w[ip+3])
|
||||
endfor
|
||||
|
||||
return v
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Doniach-Sunjic shapes
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/// Doniach-Sunjic line shape
|
||||
///
|
||||
/// [S. Doniach, M. Sunjic, J. Phys. C 3 (1970) 285]
|
||||
///
|
||||
/// @param x independent variable
|
||||
/// @param amp amplitude
|
||||
/// @param pos position
|
||||
/// @param sing singularity index (0 <= sing < 1)
|
||||
/// @param fwhm full width at half maximum
|
||||
///
|
||||
threadsafe function DoniachSunjic(x, amp, pos, sing, fwhm)
|
||||
// Doniach-Sunjic line shape
|
||||
// [S. Doniach, M. Sunjic, J. Phys. C 3 (1970) 285]
|
||||
variable x // independent variable
|
||||
variable amp // amplitude
|
||||
variable pos // position
|
||||
variable sing // singularity index (0 <= sing < 1)
|
||||
variable fwhm // width
|
||||
variable x
|
||||
variable amp
|
||||
variable pos
|
||||
variable sing
|
||||
variable fwhm
|
||||
|
||||
variable nom, denom
|
||||
nom = cos(pi * sing / 2 + (1 - sing) * atan((x - pos) / fwhm * 2))
|
||||
@ -35,6 +151,35 @@ threadsafe function DoniachSunjic(x, amp, pos, sing, fwhm)
|
||||
return amp * nom / denom * fwhm / 2
|
||||
end
|
||||
|
||||
/// multiple doniach-sunjic peaks on a linear background fit function.
|
||||
///
|
||||
///
|
||||
/// @param w shape parameters.
|
||||
/// the length of the wave defines the number of peaks.
|
||||
/// @arg w[0] = constant coefficient of background
|
||||
/// @arg w[1] = linear coefficient of background
|
||||
/// @arg w[2 + (i-1) * 4] = amplitude of peak i
|
||||
/// @arg w[3 + (i-1) * 4] = position of peak i
|
||||
/// @arg w[4 + (i-1) * 4] = width (fwhm) of peak i
|
||||
/// @arg w[5 + (i-1) * 4] = singularity index (0...1) of peak i
|
||||
/// @param x independent variable
|
||||
///
|
||||
function MultiDoniachSunjicLinBG(w,x) : FitFunc
|
||||
wave w
|
||||
variable x
|
||||
|
||||
variable np = numpnts(w)
|
||||
variable ip
|
||||
|
||||
variable v = w[0] + x * w[1]
|
||||
for (ip = 2; ip < np; ip += 4)
|
||||
v += DoniachSunjic(x, w[ip], w[ip+1], w[ip+3], w[ip+2])
|
||||
endfor
|
||||
|
||||
return v
|
||||
end
|
||||
|
||||
|
||||
threadsafe function ds1_bg(w, x): FitFunc
|
||||
// Doniach-Sunjic fit function
|
||||
// 0 <= sing < 1
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma rtGlobals=1 // Use modern global access method.
|
||||
#pragma ModuleName = PearlMenu
|
||||
#pragma version = 1.01
|
||||
#pragma version = 1.02
|
||||
|
||||
// main menu for PEARL data acquisition and analysis packages
|
||||
|
||||
@ -54,6 +54,11 @@ menu "PEARL"
|
||||
help = {"Gizmo display of 3D data", "Requires ARPES package"}
|
||||
end
|
||||
|
||||
submenu "Process"
|
||||
PearlMenuEnableFunc("asp_show_panel") + "XPD scans", /Q, asp_show_panel()
|
||||
help = {"Data processing of two-pi angle scans", "Requires ARPES package"}
|
||||
end
|
||||
|
||||
submenu "Services"
|
||||
PearlMenuEnableFunc("pearl_elog") + "Open ELOG Panel", /Q, pearl_elog("")
|
||||
help = {"Open an ELOG panel to send entries to an ELOG logbook"}
|
||||
|
@ -1,12 +1,11 @@
|
||||
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
|
||||
#pragma IgorVersion = 6.36
|
||||
#pragma ModuleName = PearlPShellImport
|
||||
#pragma version = 1.03
|
||||
#include <HDF5 Browser>
|
||||
#include "pearl-gui-tools"
|
||||
#include "pearl-area-import"
|
||||
|
||||
// copyright (c) 2013-16 Paul Scherrer Institut
|
||||
// copyright (c) 2013-18 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.
|
||||
@ -47,6 +46,14 @@
|
||||
/// - psh5_list_scan_datasets()
|
||||
/// - psh5_load_scan_meta()
|
||||
/// - psh5_load_scan_attrs()
|
||||
///
|
||||
/// @author matthias muntwiler, matthias.muntwiler@psi.ch
|
||||
///
|
||||
/// @copyright 2013-18 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
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
/// @namespace PearlPShellImport
|
||||
/// @brief import data from PShell
|
||||
@ -1728,6 +1735,12 @@ end
|
||||
/// @arg `lo[%%scan]` scan dimension.
|
||||
/// @arg `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".
|
||||
///
|
||||
/// @param data data wave to be scaled.
|
||||
/// dimension labels (index -1) must be set to match the limit waves.
|
||||
///
|
||||
@ -1754,28 +1767,45 @@ function ps_scale_dataset_2(data, ax, lo, hi, un)
|
||||
wave hi
|
||||
wave /t un
|
||||
|
||||
string snote = note(data)
|
||||
string sdim
|
||||
sdim = GetDimLabel(data, 0, -1)
|
||||
if (strlen(sdim))
|
||||
setscale /i x lo[%$sdim], hi[%$sdim], un[%$sdim], data
|
||||
Note data, "AxisLabelX=" + ax[%$sdim]
|
||||
snote = ReplaceStringByKey("AxisLabelX", snote, ax[%$sdim], "=", "\r")
|
||||
endif
|
||||
|
||||
sdim = GetDimLabel(data, 1, -1)
|
||||
if (strlen(sdim))
|
||||
setscale /i y lo[%$sdim], hi[%$sdim], un[%$sdim], data
|
||||
Note data, "AxisLabelY=" + ax[%$sdim]
|
||||
snote = ReplaceStringByKey("AxisLabelY", snote, ax[%$sdim], "=", "\r")
|
||||
endif
|
||||
|
||||
sdim = GetDimLabel(data, 2, -1)
|
||||
if (strlen(sdim))
|
||||
setscale /i z lo[%$sdim], hi[%$sdim], un[%$sdim], data
|
||||
Note data, "AxisLabelZ=" + ax[%$sdim]
|
||||
snote = ReplaceStringByKey("AxisLabelZ", snote, ax[%$sdim], "=", "\r")
|
||||
endif
|
||||
|
||||
|
||||
string data_unit = un[%$kDataDimLabel]
|
||||
string data_label = ax[%$kDataDimLabel]
|
||||
if (cmpstr(data_unit, "arb.") == 0)
|
||||
string s
|
||||
variable def = (cmpstr(data_unit, "arb.") == 0) && (cmpstr(data_label, "value") == 0)
|
||||
|
||||
if (def)
|
||||
s = StringByKey("AxisLabelD", snote, "=", "\r")
|
||||
if (strlen(s) > 0)
|
||||
data_label = s
|
||||
def = 0
|
||||
endif
|
||||
s = StringByKey("AxisUnitD", snote, "=", "\r")
|
||||
if (strlen(s) > 0)
|
||||
data_unit = s
|
||||
def = 0
|
||||
endif
|
||||
endif
|
||||
|
||||
if (def)
|
||||
strswitch(NameOfWave(data))
|
||||
case "ScientaImage":
|
||||
case "ImageAngleDistribution":
|
||||
@ -1786,28 +1816,35 @@ function ps_scale_dataset_2(data, ax, lo, hi, un)
|
||||
data *= kDetectorSensitivity
|
||||
data_unit = "counts"
|
||||
data_label = "intensity"
|
||||
def = 0
|
||||
break
|
||||
case "SampleCurrent":
|
||||
case "RefCurrent":
|
||||
case "AuxCurrent":
|
||||
data_unit = "A"
|
||||
data_label = "current"
|
||||
def = 0
|
||||
break
|
||||
case "MachineCurrent":
|
||||
data_unit = "mA"
|
||||
data_label = "current"
|
||||
def = 0
|
||||
break
|
||||
endswitch
|
||||
endif
|
||||
|
||||
setscale d 0, 0, data_unit, data
|
||||
Note data, "AxisLabelD=" + data_label
|
||||
Note data, "Dataset=" + NameOfWave(data)
|
||||
snote = ReplaceStringByKey("AxisLabelD", snote, data_label, "=", "\r")
|
||||
snote = ReplaceStringByKey("AxisUnitD", snote, data_unit, "=", "\r")
|
||||
snote = ReplaceStringByKey("Dataset", snote, NameOfWave(data), "=", "\r")
|
||||
note /k data, snote
|
||||
end
|
||||
|
||||
/// 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. @ref 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.
|
||||
@ -1817,14 +1854,21 @@ end
|
||||
/// 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.
|
||||
///
|
||||
/// @param ANickName destination folder name (top level under root).
|
||||
///
|
||||
/// @param APathName igor symbolic path name. can be empty if the path is specified in FileName or a dialog box should be displayed.
|
||||
///
|
||||
/// @param AFileName if empty a dialog box shows up.
|
||||
///
|
||||
/// @param reduction_func custom reduction function
|
||||
/// (any user-defined function which has the same parameters as adh5_default_reduction())
|
||||
/// @param reduction_func custom data reduction function.
|
||||
/// this can be any user-defined function which has the same parameters as @ref adh5_default_reduction.
|
||||
/// some reduction functions are predefined in the @ref PearlScientaPreprocess module.
|
||||
///
|
||||
/// @param reduction_param parameter string for the reduction function.
|
||||
///
|
||||
@ -1832,8 +1876,13 @@ end
|
||||
/// @arg 1 (default) show progress window
|
||||
/// @arg 0 do not show progress window
|
||||
///
|
||||
/// @return semicolon-separated list of the loaded waves,
|
||||
/// `ReducedData1` and `ReducedData2` if successful.
|
||||
/// @param nthreads
|
||||
/// @arg -1 (default) use as many threads as there are processor cores (in addition to main thread).
|
||||
/// @arg 0 use main thread only (for debugging and profiling).
|
||||
/// @arg >= 1 use a fixed number of (additional) threads.
|
||||
///
|
||||
/// @return 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.
|
||||
///
|
||||
@ -1841,20 +1890,22 @@ end
|
||||
///
|
||||
/// @return global string s_scanpaths in new data folder contains a list of scan groups inside the file.
|
||||
///
|
||||
/// @todo load scan positions.
|
||||
///
|
||||
function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [progress])
|
||||
function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [progress, nthreads])
|
||||
string ANickName
|
||||
string APathName
|
||||
string AFileName
|
||||
funcref adh5_default_reduction reduction_func
|
||||
string reduction_param
|
||||
variable progress
|
||||
variable nthreads
|
||||
|
||||
if (ParamIsDefault(progress))
|
||||
progress = 1
|
||||
endif
|
||||
|
||||
if (ParamIsDefault(nthreads))
|
||||
nthreads = -1
|
||||
endif
|
||||
|
||||
dfref saveDF = GetDataFolderDFR()
|
||||
|
||||
// performance monitoring
|
||||
@ -1904,7 +1955,7 @@ function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, r
|
||||
setdatafolder dataDF
|
||||
string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
|
||||
string dataset = select_dataset(datasets, "ScientaImage")
|
||||
wavenames = psh5_load_dataset_reduced(fileID, scanpath, dataset, reduction_func, reduction_param, progress=progress)
|
||||
wavenames = psh5_load_dataset_reduced(fileID, scanpath, dataset, reduction_func, reduction_param, progress=progress, nthreads=nthreads)
|
||||
|
||||
psh5_close_file(fileID)
|
||||
endif
|
||||
@ -1922,7 +1973,7 @@ end
|
||||
///
|
||||
/// 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` and `ReducedData2` waves.
|
||||
/// 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.
|
||||
@ -1946,8 +1997,9 @@ end
|
||||
/// 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".
|
||||
///
|
||||
/// @param reduction_func custom reduction function
|
||||
/// (any user-defined function which has the same parameters as adh5_default_reduction()).
|
||||
/// @param reduction_func custom data reduction function.
|
||||
/// this can be any user-defined function which has the same parameters as @ref adh5_default_reduction.
|
||||
/// some reduction functions are predefined in the @ref PearlScientaPreprocess module.
|
||||
///
|
||||
/// @param reduction_param parameter string for the reduction function.
|
||||
///
|
||||
@ -1957,11 +2009,11 @@ end
|
||||
///
|
||||
/// @param nthreads
|
||||
/// @arg -1 (default) use as many threads as there are processor cores (in addition to main thread).
|
||||
/// @arg 0 use main thread only (e.g. for debugging the reduction function).
|
||||
/// @arg 0 use main thread only (for debugging and profiling).
|
||||
/// @arg >= 1 use a fixed number of (additional) threads.
|
||||
///
|
||||
/// @return semicolon-separated list of the loaded waves,
|
||||
/// `ReducedData1` and `ReducedData2` if successful.
|
||||
/// @return 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.
|
||||
///
|
||||
@ -2079,6 +2131,10 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
|
||||
variable iz, it, izt
|
||||
string dfname
|
||||
variable iw, nw
|
||||
string sw
|
||||
make /n=0 /free /wave result_waves
|
||||
|
||||
izt = 0
|
||||
for (iz = 0; iz < nz; iz += 1)
|
||||
for (it = 0; it < nt; it += 1)
|
||||
@ -2102,9 +2158,10 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
processing_folders[izt] = GetDataFolderDFR()
|
||||
make /n=1/d profile1, profile2
|
||||
wave slabdata
|
||||
variable /g func_result
|
||||
func_result = reduce_slab_image(slabdata, image, profile1, profile2, reduction_func, func_param)
|
||||
WaveClear slabdata, image, profile1, profile2
|
||||
wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
|
||||
variable /g func_result = numpnts(reduced_waves)
|
||||
adh5_get_result_waves(reduced_waves, "redw_", 0)
|
||||
WaveClear slabdata, image, reduced_waves
|
||||
setdatafolder ::
|
||||
endif
|
||||
|
||||
@ -2159,31 +2216,36 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
nvar rr = dfr:r_index
|
||||
nvar ss = dfr:s_index
|
||||
nvar func_result = dfr:func_result
|
||||
wave profile1 = dfr:profile1
|
||||
wave profile2 = dfr:profile2
|
||||
|
||||
if (func_result == 0)
|
||||
if (izt == 0)
|
||||
make /n=(dimsize(profile1, 0), nz, nt) /d /o ReducedData1
|
||||
make /n=(dimsize(profile2, 0), nz, nt) /d /o ReducedData2
|
||||
setdimlabel 0, -1, $getdimlabel(profile1, 0, -1), ReducedData1
|
||||
setdimlabel 0, -1, $getdimlabel(profile2, 0, -1), ReducedData2
|
||||
setdimlabel 1, -1, $kScanDimLabel, ReducedData1
|
||||
setdimlabel 1, -1, $kScanDimLabel, ReducedData2
|
||||
ps_scale_dataset(ReducedData1)
|
||||
ps_scale_dataset(ReducedData2)
|
||||
setscale /p x dimoffset(profile1, 0), dimdelta(profile1, 0), waveunits(profile1, 0), ReducedData1
|
||||
setscale /p x dimoffset(profile2, 0), dimdelta(profile2, 0), waveunits(profile2, 0), ReducedData2
|
||||
setscale d 0, 0, waveunits(profile1, -1), ReducedData1
|
||||
setscale d 0, 0, waveunits(profile2, -1), ReducedData2
|
||||
endif
|
||||
ReducedData1[][rr][ss] = profile1[p]
|
||||
ReducedData2[][rr][ss] = profile2[p]
|
||||
else
|
||||
if (func_result < 1)
|
||||
print "error during data reduction."
|
||||
result = -3
|
||||
break
|
||||
endif
|
||||
|
||||
if (numpnts(result_waves) == 0)
|
||||
redimension /n=(func_result) result_waves
|
||||
for (iw = 0; iw < func_result; iw += 1)
|
||||
sw = "redw_" + num2str(iw)
|
||||
wave profile = dfr:$sw
|
||||
sw = "ReducedData" + num2str(iw+1)
|
||||
make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
|
||||
wave data = $sw
|
||||
setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
|
||||
setdimlabel 1, -1, $kScanDimLabel, data
|
||||
note data, note(profile)
|
||||
ps_scale_dataset(data)
|
||||
setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
|
||||
setscale d 0, 0, waveunits(profile, -1), data
|
||||
result_waves[iw] = data
|
||||
endfor
|
||||
endif
|
||||
for (iw = 0; iw < func_result; iw += 1)
|
||||
sw = "redw_" + num2str(iw)
|
||||
wave profile = dfr:$sw
|
||||
wave data = result_waves[iw]
|
||||
data[][rr][ss] = profile[p]
|
||||
endfor
|
||||
endfor
|
||||
|
||||
if (nthreads > 0)
|
||||
@ -2199,14 +2261,17 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
endif
|
||||
|
||||
if (result == 0)
|
||||
if (nz == 1)
|
||||
redimension /n=(-1, 0, 0) ReducedData1
|
||||
redimension /n=(-1, 0, 0) ReducedData2
|
||||
elseif (nt == 1)
|
||||
redimension /n=(-1, nz, 0) ReducedData1
|
||||
redimension /n=(-1, nz, 0) ReducedData2
|
||||
endif
|
||||
wavenames = "ReducedData1;ReducedData2;"
|
||||
nw = numpnts(result_waves)
|
||||
wavenames = ""
|
||||
for (iw = 0; iw < nw; iw += 1)
|
||||
wave data = result_waves[iw]
|
||||
if (nz == 1)
|
||||
redimension /n=(-1, 0, 0) data
|
||||
elseif (nt == 1)
|
||||
redimension /n=(-1, nz, 0) data
|
||||
endif
|
||||
wavenames += nameofwave(data) + ";"
|
||||
endfor
|
||||
endif
|
||||
if (progress)
|
||||
kill_progress_panel()
|
||||
@ -2240,14 +2305,14 @@ threadsafe static function reduce_slab_worker(reduction_func)
|
||||
|
||||
// do the work
|
||||
newdatafolder /s outDF
|
||||
make /n=1/d profile1, profile2
|
||||
variable /g r_index = rr
|
||||
variable /g s_index = ss
|
||||
variable /g func_result
|
||||
func_result = reduce_slab_image(slabdata, image, profile1, profile2, reduction_func, func_param)
|
||||
wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
|
||||
variable /g func_result = numpnts(reduced_waves)
|
||||
|
||||
// send output to queue and clean up
|
||||
WaveClear slabdata, image, profile1, profile2
|
||||
adh5_get_result_waves(reduced_waves, "redw_", 0)
|
||||
WaveClear slabdata, image, reduced_waves
|
||||
ThreadGroupPutDF 0, :
|
||||
KillDataFolder dfr
|
||||
while (1)
|
||||
@ -2255,18 +2320,16 @@ threadsafe static function reduce_slab_worker(reduction_func)
|
||||
return 0
|
||||
end
|
||||
|
||||
threadsafe static function reduce_slab_image(slabdata, image, profile1, profile2, reduction_func, reduction_param)
|
||||
threadsafe static function /wave reduce_slab_image(slabdata, image, reduction_func, reduction_param)
|
||||
wave slabdata
|
||||
wave image
|
||||
wave profile1
|
||||
wave profile2
|
||||
funcref adh5_default_reduction reduction_func
|
||||
string reduction_param
|
||||
|
||||
// the multiplication by detector sensitivity assumes that we are loading a ScientaImage.
|
||||
image = slabdata[q][p][0][0] * kDetectorSensitivity
|
||||
|
||||
return reduction_func(image, profile1, profile2, reduction_param)
|
||||
return reduction_func(image, reduction_param)
|
||||
end
|
||||
|
||||
/// load descriptive info from a PShell data file.
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user