update pshell explorer and data import, misc. improvements

FEATURES

- pshell: convert scienta data to true counts
- pre-process: add gauss2_reduction data reduction function
- anglescan: add set_contrast and normalize_strip_phi functions
- explorer: show info about multi-region scans
- documentation: add detailed instructions for angle-scan processing

BUGFIXES

- explorer: fix attributes notebook
- pshell: fix progress bar
- elog: increase the number of accepted attachments
This commit is contained in:
2017-09-21 12:36:30 +02:00
parent 0a436db00b
commit cf1399e59c
137 changed files with 1824 additions and 853 deletions

View File

@ -1,11 +1,12 @@
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
#pragma IgorVersion = 6.1
#pragma ModuleName = PearlScientaPreprocess
#pragma version = 1.02
#pragma version = 1.03
#include "mm-fitfuncs"
// $Id$
// author: matthias.muntwiler@psi.ch
// Copyright (c) 2013-14 Paul Scherrer Institut
// Copyright (c) 2013-17 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.
@ -21,7 +22,7 @@
///
/// @author matthias muntwiler, matthias.muntwiler@psi.ch
///
/// @copyright 2013-15 Paul Scherrer Institut @n
/// @copyright 2013-17 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
@ -799,3 +800,198 @@ threadsafe function redim_linbg_reduction(source, dest1, dest2, param)
return int_linbg_reduction(source_redim, dest1, dest2, param)
end
// DblGaussLinBG function fit reduction
/// apply the gauss2_reduction function to a single image
///
/// useful for testing or manual processing.
/// to debug, (temporarily) remove the threadsafe attribute from the gauss2_reduction function.
///
function test_gauss2_reduction(image)
wave image
string param = ""
param = ReplaceNumberByKey("rngl", param, -inf, "=", ";")
param = ReplaceNumberByKey("rngh", param, inf, "=", ";")
param = ReplaceNumberByKey("pos1", param, 113.70, "=", ";")
param = ReplaceNumberByKey("wid1", param, 1.46, "=", ";")
param = ReplaceNumberByKey("pos2", param, 126.53, "=", ";")
param = ReplaceNumberByKey("wid2", param, 1.63, "=", ";")
param = ReplaceNumberByKey("ybox", param, 1, "=", ";")
param = ReplaceStringByKey("return", param, "amp1", "=", ";")
make /o test1
make /o test2
gauss2_reduction(image, test1, test2, param)
end
/// prompt for the gauss2_reduction parameters
///
/// useful for testing or manual processing.
/// to debug, (temporarily) remove the threadsafe attribute from the gauss2_reduction function.
///
function prompt_gauss2_reduction(param)
string &param
variable rngl = NumberByKey("rngl", param, "=", ";")
variable rngh = NumberByKey("rngh", param, "=", ";")
variable pos1 = NumberByKey("pos1", param, "=", ";")
variable wid1 = NumberByKey("wid1", param, "=", ";")
variable pos2 = NumberByKey("pos2", param, "=", ";")
variable wid2 = NumberByKey("wid2", param, "=", ";")
variable ybox = NumberByKey("ybox", param, "=", ";")
string retpar = StringByKey("return", param, "=", ";")
prompt rngl, "range low"
prompt rngh, "range high"
prompt pos1, "position 1"
prompt wid1, "width 1"
prompt pos2, "position 2"
prompt wid2, "width 2"
prompt ybox, "ybox (1 or 3)"
prompt retpar, "return", popup "amp1;amp2;"
doprompt "gauss2_reduction reduction parameters", rngl, rngh, pos1, wid1, pos2, wid2, ybox, retpar
if (v_flag == 0)
param = ReplaceNumberByKey("rngl", param, rngl, "=", ";")
param = ReplaceNumberByKey("rngh", param, rngh, "=", ";")
param = ReplaceNumberByKey("pos1", param, pos1, "=", ";")
param = ReplaceNumberByKey("wid1", param, wid1, "=", ";")
param = ReplaceNumberByKey("pos2", param, pos2, "=", ";")
param = ReplaceNumberByKey("wid2", param, wid2, "=", ";")
param = ReplaceStringByKey("return", param, retpar, "=", ";")
param = ReplaceNumberByKey("ybox", param, ybox, "=", ";")
endif
return v_flag
end
/// fit horizontal cuts of an image with two gaussian peaks on a linear background
///
/// the function fits each horizontal profile (EDC) with two gaussian peaks on a linear background.
/// the position and width of the peaks is kept fixed according to input parameters.
/// the peak amplitude is constrained to positive value.
///
/// the width parameter is defined as in Igor's gauss curve fit function
/// (standard deviation divided by the square root of two).
/// the return value in dest1 is the integrated peak either of peak 1 or peak 2.
/// dest2 returns the corresponding error estimate.
///
/// @param source source wave.
/// two-dimensional distribution of counts.
/// for correct weighting and error estimation it is important
/// that the source wave contains actual counts (Poisson statistics).
/// @param dest1 (out) peak area
/// @param dest2 (out) error estimate of peak area
/// @param param (in, out) semicolon-separated key=value list of processing parameters.
/// this is a pass-by-reference argument.
/// the following parameters are required.
/// position, width and limit parameters are on the x (energy) scale.
/// @arg rngl low limit of fit interval
/// @arg rngh high limit of fit interval
/// @arg pos1 position of peak 1
/// @arg wid1 width of peak 1
/// @arg pos2 position of peak 2
/// @arg wid2 width of peak 2
/// @arg return select result to return, either "int1" or "int2".
/// @arg ybox box size of averaging in y direction, must be 1 or 3.
/// other values lead to corrupt data.
///
/// @return zero if successful, non-zero if an error occurs.
///
threadsafe function gauss2_reduction(source, dest1, dest2, param)
wave source
wave dest1, dest2
string &param
variable nx = dimsize(source, 0)
variable ny = dimsize(source, 1)
// prepare output
adh5_setup_profile(source, dest1, 1)
adh5_setup_profile(source, dest2, 1)
dest1 = 0
dest2 = 0
// read parameters
variable rngl = NumberByKey("rngl", param, "=", ";")
variable rngh = NumberByKey("rngh", param, "=", ";")
variable pos1 = NumberByKey("pos1", param, "=", ";")
variable wid1 = NumberByKey("wid1", param, "=", ";")
variable pos2 = NumberByKey("pos2", param, "=", ";")
variable wid2 = NumberByKey("wid2", param, "=", ";")
variable ybox = NumberByKey("ybox", param, "=", ";")
string retpar = StringByKey("return", param, "=", ";")
variable idestcoef
if (cmpstr(retpar, "amp2") == 0)
idestcoef = 3
else
idestcoef = 0
endif
// prepare curve fit
make /free xprof
adh5_setup_profile(source, xprof, 0)
duplicate /free xprof, xprof_sig
make /free /d /n=8 w_coef, W_sigma
w_coef[0] = {1, pos1, wid1, 1, pos2, wid2, 0, 0}
variable pl = max(x2pnt(xprof, rngl), 0)
variable ph = min(x2pnt(xprof, rngh), numpnts(xprof) - 1)
// text constraints cannot be used in threadsafe functions.
// the following matrix-vector forumlation is equivalent to:
// make /free /T /N=4 constraints
// constraints[0] = {"K0 >= 0", "K3 >= 0", "K6 <= 0", "K7 => 0"}
make /free /n=(4,8) cmat
make /free /n=4 cvec
cmat = 0
cmat[0][0] = -1
cmat[1][3] = -1
cmat[2][6] = 1
cmat[3][7] = -1
cvec = 0
// loop over angle scale
variable p0 = 0
variable p1 = numpnts(dest1) - 1
variable pp
variable wmin
variable wmax
if (ybox > 1)
p0 += ceil((ybox - 1) / 2)
p1 -= ceil((ybox - 1) / 2)
endif
variable V_FitNumIters
for (pp = p0; pp <= p1; pp += 1)
xprof = source[p][pp]
if (ybox > 1)
xprof += source[p][pp-1] + source[p][pp+1]
endif
xprof_sig = max(sqrt(xprof), 1)
xprof /= ybox
xprof_sig /= ybox
wmin = wavemin(xprof)
wmax = wavemax(xprof)
w_coef[0] = wmax - wmin
w_coef[3] = w_coef[0]
w_coef[6] = 0
w_coef[7] = wmin
FuncFit /H="01101100" /Q /NTHR=1 /N /W=2 DblGaussLinBG w_coef xprof[pl,ph] /C={cmat, cvec} /I=1 /W=xprof_sig[pl,ph]
wave w_sigma
if (V_FitNumIters < 40)
dest1[pp] = max(w_coef[idestcoef], 0)
dest2[pp] = max(w_sigma[idestcoef], 0)
endif
endfor
dest1 *= w_coef[idestcoef+2] * sqrt(pi)
dest2 *= w_coef[idestcoef+2] * sqrt(pi)
return 0
end