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:
@ -1,12 +1,12 @@
|
||||
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
|
||||
#pragma version = 1.7
|
||||
#pragma version = 1.8
|
||||
#pragma IgorVersion = 6.2
|
||||
#pragma ModuleName = PearlAnglescanProcess
|
||||
#include "pearl-vector-operations"
|
||||
#include "pearl-polar-coordinates"
|
||||
#include <New Polar Graphs>
|
||||
|
||||
// copyright (c) 2013-16 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.
|
||||
@ -64,13 +64,13 @@
|
||||
///
|
||||
/// @author matthias muntwiler, matthias.muntwiler@psi.ch
|
||||
///
|
||||
/// @copyright 2013-16 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
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// @version 1.6
|
||||
/// @version 1.8
|
||||
/// canonical orientation of spherical coordinate system.
|
||||
///
|
||||
|
||||
@ -241,6 +241,84 @@ function normalize_strip_x(strip, [smooth_method, smooth_factor, check])
|
||||
endif
|
||||
end
|
||||
|
||||
/// divide the strip by a sine function in phi (wobble correction).
|
||||
///
|
||||
/// the sine function is a curve fit to the intensity integrated over detector angle
|
||||
/// with a period of 360°ree;.
|
||||
///
|
||||
/// this normalization may be useful if the intensity varies with a 360°ree; periodicity in the azimuthal angle,
|
||||
/// e.g. due to misalignment of the surface normal and the azimuthal rotation axis of the manipulator (wobble).
|
||||
/// note, however, that this function does not correct other effects of wobble such as angle shifts.
|
||||
///
|
||||
/// the strip is normalized in place, previous data is overwritten.
|
||||
///
|
||||
/// @param[in,out] strip 2D data, X-axis = analyser angle, Y-axis = arbitrary manipulator scan
|
||||
/// @param[in] theta polar manipulator angle.
|
||||
/// @param[in] phi azimuthal manipulator angle, arbitrary offset.
|
||||
/// @param[in] theta_offset theta value corresponding to normal emission (default 0).
|
||||
/// @param[in] theta_range maximum (offset corrected) theta to consider in the sine fit (default 10).
|
||||
///
|
||||
/// @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_phi(strip, theta, phi, [theta_offset, theta_range, check])
|
||||
wave strip
|
||||
wave theta
|
||||
wave phi
|
||||
variable theta_offset
|
||||
variable theta_range
|
||||
variable check
|
||||
|
||||
if (ParamIsDefault(check))
|
||||
check = 0
|
||||
endif
|
||||
if (ParamIsDefault(theta_offset))
|
||||
theta_offset = 0
|
||||
endif
|
||||
if (ParamIsDefault(theta_range))
|
||||
theta_offset = 10
|
||||
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
|
||||
duplicate /free phi, phi_int
|
||||
setscale /p x phi_int[0], phi_int[1] - phi_int[0], waveunits(phi, -1), dist, dist_smoo
|
||||
|
||||
extract /free /indx dist, red_idx, theta_int < theta_range
|
||||
duplicate /free red_idx, red_dist, red_phi
|
||||
red_dist = dist[red_idx]
|
||||
red_phi = phi_int[red_idx]
|
||||
|
||||
variable wavg = mean(red_dist)
|
||||
make /n=4 /d /free coef
|
||||
coef[0] = {wavg, wavg/100, pi/180, 0}
|
||||
CurveFit /q /h="0010" /g /w=2 sin, kwcWave=coef, red_dist /x=red_phi
|
||||
dist_smoo = coef[0] + coef[1] * sin(coef[2] * phi_int[p] + coef[3])
|
||||
|
||||
// divide
|
||||
if (check != 2)
|
||||
strip = strip / dist_smoo[q] * coef[0]
|
||||
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 the average polar distribution.
|
||||
///
|
||||
/// this is a simple way to remove the polar angle dependence.
|
||||
@ -2843,3 +2921,112 @@ function /wave hemi_azi_cut(nickname, pol)
|
||||
return $""
|
||||
endif
|
||||
end
|
||||
|
||||
static function check_contrast(values, pcmin, pcmax, vmin, vmax)
|
||||
wave values
|
||||
variable pcmin
|
||||
variable pcmax
|
||||
variable &vmin
|
||||
variable &vmax
|
||||
|
||||
dfref save_df = GetDataFolderDFR()
|
||||
dfref dfr = NewFreeDataFolder()
|
||||
setdatafolder dfr
|
||||
StatsQuantiles /inan /iw /q /z values
|
||||
wave index = w_quantilesindex
|
||||
variable imin = round(numpnts(index) * pcmin / 100)
|
||||
variable imax = round(numpnts(index) * (100 - pcmax) / 100)
|
||||
vmin = values[index[imin]]
|
||||
vmax = values[index[imax]]
|
||||
KillDataFolder dfr
|
||||
setdatafolder save_df
|
||||
end
|
||||
|
||||
/// set the pseudocolor contrast by percentile.
|
||||
///
|
||||
/// set the minimum and maximum values of the pseudocolor scale
|
||||
/// such that a specified percentile of the distribution lies outside the limits.
|
||||
///
|
||||
/// the new contrast is applied to traces and images of the selected graph
|
||||
/// that have pseudocolor tables.
|
||||
///
|
||||
/// the function is not specific to angle scans.
|
||||
/// it can be used for any pseudocolor trace or image plots except contour plots.
|
||||
///
|
||||
/// @param pcmin percentile below the minimum color (0-100).
|
||||
/// @param pcmax percentile above the maximum color (0-100).
|
||||
/// @param graphname name of graph. default: top graph.
|
||||
/// @param colortable name of new colortable. default: keep current table.
|
||||
///
|
||||
function set_contrast(pcmin, pcmax, [graphname, colortable])
|
||||
variable pcmin
|
||||
variable pcmax
|
||||
string graphname
|
||||
string colortable
|
||||
|
||||
if (ParamIsDefault(graphname))
|
||||
graphname = ""
|
||||
endif
|
||||
if (ParamIsDefault(colortable))
|
||||
colortable = ""
|
||||
endif
|
||||
|
||||
dfref save_df = GetDataFolderDFR()
|
||||
|
||||
string objname
|
||||
string info
|
||||
string wname
|
||||
string ctab
|
||||
variable rev
|
||||
variable n
|
||||
variable i
|
||||
variable vmin
|
||||
variable vmax
|
||||
|
||||
string traces = TraceNameList(graphname, ";", 1+4)
|
||||
n = ItemsInList(traces, ";")
|
||||
for (i = 0; i < n; i += 1)
|
||||
objname = StringFromList(i, traces, ";")
|
||||
info = TraceInfo(graphname, objname, 0)
|
||||
if (strlen(info) > 0)
|
||||
info = StringByKey("RECREATION", info, ":", ";")
|
||||
info = StringByKey("zColor(x)", info, "=", ";")
|
||||
if (strlen(info) > 2)
|
||||
info = info[1,strlen(info)-2]
|
||||
wname = StringFromList(0, info, ",")
|
||||
wave w = $wname
|
||||
ctab = StringFromList(3, info, ",")
|
||||
rev = str2num("0" + StringFromList(4, info, ","))
|
||||
if (strlen(colortable) > 0)
|
||||
ctab = colortable
|
||||
endif
|
||||
check_contrast(w, pcmin, pcmax, vmin, vmax)
|
||||
ModifyGraph /w=$graphname zColor($objname)={w, vmin, vmax, $ctab, rev}
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
string images = ImageNameList(graphname, ";")
|
||||
n = ItemsInList(images, ";")
|
||||
for (i = 0; i < n; i += 1)
|
||||
objname = StringFromList(i, images, ";")
|
||||
wave w = ImageNameToWaveRef(graphname, objname)
|
||||
info = ImageInfo(graphname, objname, 0)
|
||||
if (strlen(info) > 0)
|
||||
info = StringByKey("RECREATION", info, ":", ";")
|
||||
info = StringByKey("ctab", info, "=", ";")
|
||||
if (strlen(info) > 2)
|
||||
info = info[1,strlen(info)-2]
|
||||
ctab = StringFromList(2, info, ",")
|
||||
rev = str2num("0" + StringFromList(3, info, ","))
|
||||
if (strlen(colortable) > 0)
|
||||
ctab = colortable
|
||||
endif
|
||||
check_contrast(w, pcmin, pcmax, vmin, vmax)
|
||||
ModifyImage /w=$graphname $objname ctab={vmin, vmax, $ctab, rev}
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
|
||||
setdatafolder save_df
|
||||
end
|
||||
|
@ -1495,6 +1495,7 @@ function ad_profiles_set_slice(brick, dim, value)
|
||||
return 0
|
||||
end
|
||||
|
||||
/// set slice coordinate (slider procedure).
|
||||
static function slp_slice_position(sa) : SliderControl
|
||||
STRUCT WMSliderAction &sa
|
||||
|
||||
@ -1508,12 +1509,16 @@ static function slp_slice_position(sa) : SliderControl
|
||||
string control_datafolder = GetUserData(sa.win, "", "control_datafolder")
|
||||
setdatafolder control_datafolder
|
||||
string brick_path = GetUserData(sa.win, "", "brick_path")
|
||||
wave brick = $brick_path
|
||||
|
||||
string axis = StringFromList(1, sa.ctrlName, "_")
|
||||
variable dim = char2num(axis[0]) - char2num("x")
|
||||
ad_gizmo_set_plane(brick, dim, sa.curval)
|
||||
ad_profiles_set_slice(brick, dim, sa.curval)
|
||||
|
||||
wave /z brick = $brick_path
|
||||
if (WaveExists(brick))
|
||||
ad_gizmo_set_plane(brick, dim, sa.curval)
|
||||
ad_profiles_set_slice(brick, dim, sa.curval)
|
||||
else
|
||||
Abort "can't find original wave " + brick_path
|
||||
endif
|
||||
endif
|
||||
break
|
||||
endswitch
|
||||
@ -1535,12 +1540,16 @@ static function svp_slice_position(sva) : SetVariableControl
|
||||
string control_datafolder = GetUserData(sva.win, "", "control_datafolder")
|
||||
setdatafolder control_datafolder
|
||||
string brick_path = GetUserData(sva.win, "", "brick_path")
|
||||
wave brick = $brick_path
|
||||
|
||||
string axis = StringFromList(1, sva.ctrlName, "_")
|
||||
variable dim = char2num(axis[0]) - char2num("x")
|
||||
ad_gizmo_set_plane(brick, dim, sva.dval)
|
||||
ad_profiles_set_slice(brick, dim, sva.dval)
|
||||
|
||||
wave /z brick = $brick_path
|
||||
if (WaveExists(brick))
|
||||
ad_gizmo_set_plane(brick, dim, sva.dval)
|
||||
ad_profiles_set_slice(brick, dim, sva.dval)
|
||||
else
|
||||
Abort "can't find original wave " + brick_path
|
||||
endif
|
||||
break
|
||||
case -1: // control being killed
|
||||
break
|
||||
@ -1561,29 +1570,33 @@ static function bp_move_slice(ba) : ButtonControl
|
||||
string control_datafolder = GetUserData(ba.win, "", "control_datafolder")
|
||||
setdatafolder control_datafolder
|
||||
string brick_path = GetUserData(ba.win, "", "brick_path")
|
||||
wave brick = $brick_path
|
||||
|
||||
string axis = StringFromList(1, ba.ctrlName, "_")
|
||||
string cmd = StringFromList(2, ba.ctrlName, "_")
|
||||
variable dim = char2num(axis[0]) - char2num("x")
|
||||
string posvariable = getdatafolder(1) + axis[0] + "_slice_pos"
|
||||
|
||||
nvar pos = $(posvariable)
|
||||
strswitch (cmd)
|
||||
case "forward":
|
||||
ad_slicer_start_bg(brick, dim, posvariable, dimdelta(brick, dim))
|
||||
break
|
||||
case "back":
|
||||
ad_slicer_start_bg(brick, dim, posvariable, -dimdelta(brick, dim))
|
||||
break
|
||||
case "center":
|
||||
ad_slicer_stop_bg(posvariable)
|
||||
bp_move_slice_center(brick, dim, posvariable)
|
||||
break
|
||||
case "stop":
|
||||
ad_slicer_stop_bg(posvariable)
|
||||
break
|
||||
endswitch
|
||||
|
||||
wave /z brick = $brick_path
|
||||
if (WaveExists(brick))
|
||||
strswitch (cmd)
|
||||
case "forward":
|
||||
ad_slicer_start_bg(brick, dim, posvariable, dimdelta(brick, dim))
|
||||
break
|
||||
case "back":
|
||||
ad_slicer_start_bg(brick, dim, posvariable, -dimdelta(brick, dim))
|
||||
break
|
||||
case "center":
|
||||
ad_slicer_stop_bg(posvariable)
|
||||
bp_move_slice_center(brick, dim, posvariable)
|
||||
break
|
||||
case "stop":
|
||||
ad_slicer_stop_bg(posvariable)
|
||||
break
|
||||
endswitch
|
||||
else
|
||||
ad_slicer_stop_bg(posvariable)
|
||||
Abort "can't find original wave " + brick_path
|
||||
endif
|
||||
break
|
||||
case -1: // control being killed
|
||||
break
|
||||
|
@ -308,31 +308,44 @@ static function /wave preview_pshell_file(filename)
|
||||
string filename
|
||||
|
||||
dfref saveDF = GetDataFolderDFR()
|
||||
|
||||
setdatafolder $package_path
|
||||
dfref previewDF = GetDataFolderDFR()
|
||||
svar s_preview_file
|
||||
svar s_preview_source
|
||||
psh5_load_preview("preview_image", "pearl_explorer_filepath", filename)
|
||||
s_preview_file = filename
|
||||
s_preview_source = ""
|
||||
wave /z preview_image
|
||||
|
||||
svar /z s_file_info
|
||||
if (! svar_exists(s_file_info))
|
||||
string /g s_file_info
|
||||
endif
|
||||
|
||||
dfref tempDF = NewFreeDataFolder()
|
||||
setdatafolder tempDF
|
||||
string dataname
|
||||
dataname = psh5_load_preview("pearl_explorer_filepath", filename)
|
||||
|
||||
s_preview_file = filename
|
||||
s_preview_source = ""
|
||||
|
||||
wave /z data = $dataname
|
||||
if (waveexists(data))
|
||||
duplicate /o data, previewDF:preview_image
|
||||
else
|
||||
print "no data found in file " + filename
|
||||
endif
|
||||
|
||||
if (strlen(s_preview_file) > 0)
|
||||
s_file_info = psh5_load_info("pearl_explorer_filepath", filename)
|
||||
else
|
||||
s_file_info = ""
|
||||
endif
|
||||
|
||||
if (DataFolderExists("attr"))
|
||||
setdatafolder attr
|
||||
preview_attributes(GetDataFolderDFR())
|
||||
setdatafolder ::
|
||||
dfref attrDF = tempDF:attr
|
||||
if (DataFolderRefStatus(attrDF))
|
||||
preview_attributes(attrDF)
|
||||
endif
|
||||
|
||||
setdatafolder saveDF
|
||||
wave /z /sdfr=previewDF preview_image
|
||||
return preview_image
|
||||
end
|
||||
|
||||
@ -654,7 +667,6 @@ static function preview_attributes(attr_folder, [dest_folder, attr_filter, inclu
|
||||
attr_names = ""
|
||||
attr_values = ""
|
||||
|
||||
string /g s_attr_folder = GetDataFolder(1, attr_folder)
|
||||
setdatafolder attr_folder
|
||||
wave /t /z IN
|
||||
wave /t /z ID
|
||||
|
@ -1,10 +1,10 @@
|
||||
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
|
||||
#pragma version = 1.40
|
||||
#pragma version = 1.41
|
||||
#pragma IgorVersion = 6.2
|
||||
#pragma ModuleName = PearlElog
|
||||
|
||||
// author: matthias.muntwiler@psi.ch
|
||||
// Copyright (c) 2013-16 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.
|
||||
@ -71,7 +71,7 @@
|
||||
///
|
||||
/// @author matthias muntwiler, matthias.muntwiler@psi.ch
|
||||
///
|
||||
/// @copyright 2013-16 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
|
||||
@ -247,7 +247,7 @@ static function init_package([clean])
|
||||
variable /g port = 0 // 0 = unspecified (default)
|
||||
variable /g ssl = 0 // 0 = plain text (incl. passwords), 1 = secure connection
|
||||
string /g subdir = ""
|
||||
variable /g loglevel = 3
|
||||
variable /g loglevel = 4
|
||||
|
||||
setdatafolder savedf
|
||||
return 0
|
||||
@ -748,23 +748,27 @@ function elog_create_entry(logbook, attributes, message, [encoding, graphs, repl
|
||||
string messagefile = create_message_file(message)
|
||||
if (strlen(messagefile) > 0)
|
||||
cmd += " -m \"" + messagefile + "\""
|
||||
cmd += " > \"" + get_log_path() + "\""
|
||||
cmd += " > elog.log"
|
||||
if (loglevel >= 5)
|
||||
print cmd
|
||||
endif
|
||||
string cmd_file_path = create_cmd_file(cmd)
|
||||
ExecuteScriptText cmd_file_path
|
||||
variable id = parse_result()
|
||||
if (id > 0)
|
||||
msg_id = id
|
||||
if (loglevel >= 4)
|
||||
print "ELOG: sent message " + num2str(id)
|
||||
if (strlen(cmd_file_path) > 0)
|
||||
ExecuteScriptText cmd_file_path
|
||||
variable id = parse_result()
|
||||
if (id > 0)
|
||||
msg_id = id
|
||||
if (loglevel >= 4)
|
||||
print "ELOG: sent message " + num2str(id)
|
||||
endif
|
||||
else
|
||||
if (loglevel >= 2)
|
||||
print "ELOG: sending message failed."
|
||||
endif
|
||||
result = -4
|
||||
endif
|
||||
else
|
||||
if (loglevel >= 2)
|
||||
print "ELOG: sending message failed."
|
||||
endif
|
||||
result = -4
|
||||
result = -2
|
||||
endif
|
||||
else
|
||||
if (loglevel >= 2)
|
||||
@ -814,20 +818,24 @@ function elog_add_attachment(logbook, id, graphs)
|
||||
|
||||
if (result == 0)
|
||||
cmd += " " + cmd_graphs
|
||||
cmd += " > \"" + get_log_path() + "\""
|
||||
cmd += " > elog.log"
|
||||
string cmd_file_path = create_cmd_file(cmd)
|
||||
ExecuteScriptText cmd_file_path
|
||||
id = parse_result()
|
||||
if (id > 0)
|
||||
msg_id = id
|
||||
if (loglevel >= 4)
|
||||
print "ELOG: attached graphs to message " + num2str(id)
|
||||
if (strlen(cmd_file_path) > 0)
|
||||
ExecuteScriptText cmd_file_path
|
||||
id = parse_result()
|
||||
if (id > 0)
|
||||
msg_id = id
|
||||
if (loglevel >= 4)
|
||||
print "ELOG: attached graphs to message " + num2str(id)
|
||||
endif
|
||||
else
|
||||
if (loglevel >= 2)
|
||||
print "ELOG: failed to attach graphs."
|
||||
endif
|
||||
result = -4 // error: elog returned error
|
||||
endif
|
||||
else
|
||||
if (loglevel >= 2)
|
||||
print "ELOG: failed to attach graphs."
|
||||
endif
|
||||
result = -4 // error: elog returned error
|
||||
result = -2 // error: invalid command line
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -923,7 +931,8 @@ end
|
||||
///
|
||||
/// prepares the attachment files from Igor graph windows
|
||||
/// and returns the arguments to the elog command to attach the files.
|
||||
/// the result string does not include leading or trailing space
|
||||
/// file names are returned without path.
|
||||
/// the result string does not include leading or trailing space.
|
||||
///
|
||||
/// @param graphs names of graph windows to be added as attachments, semicolon separated
|
||||
///
|
||||
@ -954,25 +963,63 @@ static function /s get_timestamp(sep)
|
||||
return dat + sep + tim
|
||||
end
|
||||
|
||||
/// save the message to a temporary text file
|
||||
///
|
||||
/// the file is saved to the Temporary directory returned by igor's SpecialDirPath function
|
||||
/// under the file name "elog_temp_message.txt".
|
||||
/// the function returns the name of the file (excluding path!)
|
||||
///
|
||||
/// @note percent characters (%) cannot be passed to elog.
|
||||
/// they are removed silently from the message.
|
||||
///
|
||||
/// @param message text message to save to the file.
|
||||
/// @return (string) name of the created file.
|
||||
/// empty string if unsuccessful.
|
||||
///
|
||||
/// @version 1.41 the return value has changed from full path to file name only
|
||||
/// due to the limited length of the command line (1024 bytes).
|
||||
///
|
||||
static function /s create_message_file(message)
|
||||
string message
|
||||
|
||||
message = ReplaceString("%", message, "")
|
||||
string path = SpecialDirPath("Temporary", 0, 1, 0)
|
||||
variable len = strlen(path)
|
||||
string filename
|
||||
|
||||
if (numtype(len) == 0)
|
||||
path += "elog_temp_message.txt"
|
||||
filename = "elog_temp_message.txt"
|
||||
path += filename
|
||||
variable f1
|
||||
Open f1 as path
|
||||
fprintf f1, message
|
||||
Close f1
|
||||
else
|
||||
path = ""
|
||||
filename = ""
|
||||
endif
|
||||
|
||||
return path
|
||||
return filename
|
||||
end
|
||||
|
||||
/// save a graph to a temporary graphics file
|
||||
///
|
||||
/// the file is saved to the Temporary directory returned by igor's SpecialDirPath function.
|
||||
/// the file name contains a time stamp and the specified file index to make it unique.
|
||||
/// the function returns the name of the file (excluding path!)
|
||||
///
|
||||
/// the full path is added to the temp_graph_files global list.
|
||||
/// a hook function will delete the files listed there when igor quits.
|
||||
///
|
||||
/// @param graphname object name of the graph to save.
|
||||
/// @param fileindex incrememtal index of the file within one submission.
|
||||
/// the file name is made unique by a time stamp and this file index.
|
||||
/// submissions within the same second must have a unique file index.
|
||||
/// @return (string) name of the created file.
|
||||
/// empty string if unsuccessful.
|
||||
///
|
||||
/// @version 1.41 the return value has changed from full path to file name only
|
||||
/// due to the limited length of the command line (1024 bytes).
|
||||
///
|
||||
static function /s create_graph_file(graphname, fileindex)
|
||||
string graphname
|
||||
variable fileindex
|
||||
@ -983,37 +1030,66 @@ static function /s create_graph_file(graphname, fileindex)
|
||||
string path = SpecialDirPath("Temporary", 0, 1, 0)
|
||||
string ts = get_timestamp("_")
|
||||
variable len = strlen(path)
|
||||
string filename
|
||||
|
||||
if (numtype(len) == 0)
|
||||
path += "elog_" + ts + "_" + num2str(fileindex) + ".png"
|
||||
filename = "elog_" + ts + "_" + num2str(fileindex) + ".png"
|
||||
path += filename
|
||||
SavePICT /B=72 /E=-5 /M /O /W=(0,0,8,6) /WIN=$graphname /Z as path
|
||||
if (v_flag == 0)
|
||||
temp_graph_files = AddListItem(path, temp_graph_files, ";", inf)
|
||||
else
|
||||
path = ""
|
||||
filename = ""
|
||||
endif
|
||||
else
|
||||
path = ""
|
||||
filename = ""
|
||||
endif
|
||||
|
||||
return path
|
||||
return filename
|
||||
end
|
||||
|
||||
/// write the command line to a file.
|
||||
///
|
||||
/// the command script changes the working directory to the Temporary directory.
|
||||
/// it also deletes a previous elog.log file.
|
||||
///
|
||||
/// @note somewhere the command line (even inside command files) is limited to 1024 bytes.
|
||||
/// for this reason all files should now be in the Temporary directory assigned by igor.
|
||||
///
|
||||
static function /s create_cmd_file(cmd)
|
||||
string cmd
|
||||
|
||||
string path = SpecialDirPath("Temporary", 0, 1, 0)
|
||||
variable len = strlen(path)
|
||||
dfref df_general = get_elog_df("", kdfPersistent)
|
||||
nvar /sdfr=df_general loglevel
|
||||
|
||||
if (strlen(cmd) >= 1024)
|
||||
if (loglevel >= 2)
|
||||
print "ELOG: command line too long (add fewer attachments)."
|
||||
endif
|
||||
return ""
|
||||
endif
|
||||
|
||||
string work_path = SpecialDirPath("Temporary", 0, 1, 0)
|
||||
variable len = strlen(work_path)
|
||||
if (numtype(len) == 0)
|
||||
path += "elog_temp_cmd.bat"
|
||||
string cmdx
|
||||
string cmd_path = work_path + "elog_temp_cmd.bat"
|
||||
|
||||
variable f1
|
||||
Open f1 as path
|
||||
Open f1 as cmd_path
|
||||
cmdx = "c:\r\n"
|
||||
fprintf f1, cmdx
|
||||
cmdx = "cd \"" + work_path + "\"\r\n"
|
||||
fprintf f1, cmdx
|
||||
cmdx = "del elog.log"
|
||||
fprintf f1, cmdx + "\r\n"
|
||||
fprintf f1, cmd
|
||||
Close f1
|
||||
else
|
||||
path = ""
|
||||
cmd_path = ""
|
||||
endif
|
||||
|
||||
return path
|
||||
return cmd_path
|
||||
end
|
||||
|
||||
static function /s get_log_path()
|
||||
|
@ -75,6 +75,9 @@ strconstant kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChann
|
||||
/// List of datasets that should be transposed upon loading
|
||||
strconstant kTransposedDatasets = "ScientaImage;"
|
||||
|
||||
/// multiply scienta detector intensity by this value to get actual counts.
|
||||
constant kDetectorSensitivity = 4
|
||||
|
||||
/// 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,
|
||||
@ -216,11 +219,6 @@ end
|
||||
/// the data wave is loaded into the current data folder.
|
||||
/// attributes are loaded into the attr subfolder. existing waves in attr are deleted.
|
||||
///
|
||||
/// @warning EXPERIMENTAL
|
||||
/// this function uses the root:pearl_area:preview data folder. existing data there may be deleted!
|
||||
///
|
||||
/// @param ANickName destination wave name. the wave is created in the current data folder.
|
||||
///
|
||||
/// @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
|
||||
@ -242,8 +240,7 @@ end
|
||||
///
|
||||
/// @return name of loaded preview wave.
|
||||
///
|
||||
function /s psh5_load_preview(ANickName, APathName, AFileName, [load_data, load_attr, pref_scans, pref_datasets])
|
||||
string ANickName
|
||||
function /s psh5_load_preview(APathName, AFileName, [load_data, load_attr, pref_scans, pref_datasets])
|
||||
string APathName
|
||||
string AFileName
|
||||
variable load_data
|
||||
@ -265,9 +262,6 @@ function /s psh5_load_preview(ANickName, APathName, AFileName, [load_data, load_
|
||||
endif
|
||||
|
||||
dfref saveDF = GetDataFolderDFR()
|
||||
setdatafolder root:
|
||||
newdatafolder /o/s pearl_area
|
||||
newdatafolder /o/s preview
|
||||
|
||||
variable fileID
|
||||
string scanpaths = ""
|
||||
@ -319,16 +313,6 @@ function /s psh5_load_preview(ANickName, APathName, AFileName, [load_data, load_
|
||||
|
||||
setdatafolder fileDF
|
||||
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
|
||||
else
|
||||
print "no data found in file " + AFileName
|
||||
endif
|
||||
|
||||
else
|
||||
print "no scans found in file " + AFileName
|
||||
endif
|
||||
@ -903,7 +887,6 @@ function /s psh5_load_scan_preview(fileID, scanpath, [set_scale, pref_datasets])
|
||||
|
||||
setdatafolder dataDF
|
||||
newdatafolder /o/s attr
|
||||
killwaves /a/z
|
||||
psh5_load_scan_attrs(fileID, scanpath, attr_sets=2)
|
||||
setdatafolder dataDF
|
||||
ps_scale_dataset(data)
|
||||
@ -999,7 +982,7 @@ function /s psh5_load_scan_section(fileID, scanpath, dim, [set_scale, pref_datas
|
||||
ny = di.dims[idy]
|
||||
nz = di.dims[idz]
|
||||
|
||||
HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
|
||||
HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
|
||||
wave slab
|
||||
slab[][%Start] = 0
|
||||
slab[][%Stride] = 1
|
||||
@ -1197,7 +1180,7 @@ function /s psh5_load_dataset_slabs(fileID, datapath, datasetname, [progress])
|
||||
endif
|
||||
|
||||
// load data image by image
|
||||
HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
|
||||
HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
|
||||
wave slab
|
||||
slab[][%Start] = 0
|
||||
slab[][%Stride] = 1
|
||||
@ -1319,7 +1302,7 @@ function /s psh5_load_dataset_slab(fileID, datapath, datasetname, dim2start, dim
|
||||
wave data = $datawavename
|
||||
data = 0
|
||||
|
||||
HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
|
||||
HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
|
||||
wave slab
|
||||
slab[][%Start] = 0
|
||||
slab[][%Stride] = 1
|
||||
@ -1794,6 +1777,16 @@ function ps_scale_dataset_2(data, ax, lo, hi, un)
|
||||
string data_label = ax[%$kDataDimLabel]
|
||||
if (cmpstr(data_unit, "arb.") == 0)
|
||||
strswitch(NameOfWave(data))
|
||||
case "ScientaImage":
|
||||
case "ImageAngleDistribution":
|
||||
case "ScientaAngleDistribution":
|
||||
case "ScientaSpectrum":
|
||||
case "ImageEnergyDistribution":
|
||||
case "ScientaEnergyDistribution":
|
||||
data *= kDetectorSensitivity
|
||||
data_unit = "counts"
|
||||
data_label = "intensity"
|
||||
break
|
||||
case "SampleCurrent":
|
||||
case "RefCurrent":
|
||||
case "AuxCurrent":
|
||||
@ -1948,8 +1941,9 @@ end
|
||||
/// @param scanpath path to scan group in the HDF5 file.
|
||||
///
|
||||
/// @param datasetname name of the dataset.
|
||||
/// this must currently be "ScientaImage", other data is not supported.
|
||||
/// the name of the loaded wave is a cleaned up version of the dataset name.
|
||||
/// the name can include the region name as a relative path, e.g. "region1/ScientaSpectrum".
|
||||
/// 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
|
||||
@ -2050,7 +2044,7 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
nzt = nz * nt
|
||||
|
||||
// load data image by image
|
||||
HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
|
||||
HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
|
||||
wave slab
|
||||
slab[][%Start] = 0
|
||||
slab[][%Stride] = 1
|
||||
@ -2076,11 +2070,12 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
if (progress)
|
||||
display_progress_panel("HDF5 Import", "Loading data (step 1 of 2)...", nzt)
|
||||
endif
|
||||
|
||||
make /n=(nx,ny) /d /o image_template
|
||||
setdimlabel 0, -1, $kEnergyDimLabel, image_template
|
||||
setdimlabel 1, -1, $kAngleDimLabel, image_template
|
||||
ps_scale_dataset(image_template)
|
||||
|
||||
// create a template wave with the correct scales and labels
|
||||
make /n=(nx,ny) /d /o $datawavename
|
||||
wave template = $datawavename
|
||||
ps_set_dimlabels2(template, datawavename)
|
||||
ps_scale_dataset(template)
|
||||
|
||||
variable iz, it, izt
|
||||
string dfname
|
||||
@ -2093,9 +2088,9 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
dfname = "processing_" + num2str(izt)
|
||||
newdatafolder /s $dfname
|
||||
HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
|
||||
|
||||
|
||||
// send to processing queue
|
||||
duplicate image_template, image
|
||||
duplicate template, image
|
||||
variable /g r_index = iz
|
||||
variable /g s_index = it
|
||||
string /g func_param = reduction_param
|
||||
@ -2125,7 +2120,7 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
endfor
|
||||
endfor
|
||||
|
||||
killwaves /z slab, slabdata, image_template
|
||||
killwaves /z slab, slabdata, template
|
||||
if (progress)
|
||||
update_progress_panel(0, message="Processing data (step 2 of 2)...")
|
||||
endif
|
||||
@ -2134,10 +2129,6 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
for (izt = 0; (izt < nzt) && (result == 0); izt += 1)
|
||||
if (nthreads > 0)
|
||||
do
|
||||
dfr = ThreadGroupGetDFR(threadGroupID, 1000)
|
||||
if (DatafolderRefStatus(dfr) != 0)
|
||||
break
|
||||
endif
|
||||
if (progress)
|
||||
if (update_progress_panel(izt))
|
||||
print "user abort"
|
||||
@ -2145,9 +2136,12 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
break
|
||||
endif
|
||||
endif
|
||||
dfr = ThreadGroupGetDFR(threadGroupID, 1000)
|
||||
if (DatafolderRefStatus(dfr) != 0)
|
||||
break
|
||||
endif
|
||||
while (1)
|
||||
else
|
||||
dfr = processing_folders[izt]
|
||||
if (progress)
|
||||
if (update_progress_panel(izt))
|
||||
print "user abort"
|
||||
@ -2155,6 +2149,7 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
break
|
||||
endif
|
||||
endif
|
||||
dfr = processing_folders[izt]
|
||||
endif
|
||||
|
||||
if (result != 0)
|
||||
@ -2175,6 +2170,8 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
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
|
||||
@ -2210,8 +2207,6 @@ function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_f
|
||||
redimension /n=(-1, nz, 0) ReducedData2
|
||||
endif
|
||||
wavenames = "ReducedData1;ReducedData2;"
|
||||
ps_scale_dataset(ReducedData1)
|
||||
ps_scale_dataset(ReducedData2)
|
||||
endif
|
||||
if (progress)
|
||||
kill_progress_panel()
|
||||
@ -2268,7 +2263,8 @@ threadsafe static function reduce_slab_image(slabdata, image, profile1, profile2
|
||||
funcref adh5_default_reduction reduction_func
|
||||
string reduction_param
|
||||
|
||||
image = slabdata[q][p][0][0]
|
||||
// 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)
|
||||
end
|
||||
@ -2325,7 +2321,8 @@ end
|
||||
/// the info string contains up to three lines which are made up of the following information:
|
||||
/// - number of scan positions.
|
||||
/// - dataset names of scan positioners.
|
||||
/// - dataset names of detectors.
|
||||
/// - dataset names of detectors (without region names).
|
||||
/// - region names
|
||||
///
|
||||
/// @param fileID ID of open HDF5 file from psh5_open_file().
|
||||
///
|
||||
@ -2340,9 +2337,12 @@ function /s psh5_load_scan_info(fileID, scanpath)
|
||||
string info = ""
|
||||
string positions = ""
|
||||
string positioners = ""
|
||||
string readables = ""
|
||||
string detectors = ""
|
||||
string regions = ""
|
||||
|
||||
psh5_load_scan_meta(fileID, scanpath)
|
||||
|
||||
wave /z ScanDimensions
|
||||
wave /t /z ScanWritables
|
||||
wave /t /z ScanReadables
|
||||
@ -2357,10 +2357,31 @@ function /s psh5_load_scan_info(fileID, scanpath)
|
||||
positioners = "positioners = " + twave2list(ScanWritables, ",")
|
||||
info = AddListItem(positioners, info, "\r", inf)
|
||||
endif
|
||||
|
||||
variable i, m, n
|
||||
string s
|
||||
if (WaveExists(ScanReadables) && (numpnts(ScanReadables) >= 1))
|
||||
detectors = "detectors = " + twave2list(ScanReadables, ",")
|
||||
readables = twave2list(ScanReadables, ",")
|
||||
n = ItemsInList(readables, ",")
|
||||
for (i = 0; i < n; i += 1)
|
||||
s = StringFromList(i, readables, ",")
|
||||
m = ItemsInList(s, "/")
|
||||
if (m > 1)
|
||||
s = StringFromList(m - 1, s, "/")
|
||||
endif
|
||||
if (WhichListItem(s, detectors, ",") < 0)
|
||||
detectors = AddListItem(s, detectors, ",", inf)
|
||||
endif
|
||||
endfor
|
||||
detectors = "detectors = " + detectors
|
||||
info = AddListItem(detectors, info, "\r", inf)
|
||||
endif
|
||||
|
||||
regions = psh5_list_scan_regions(fileID, scanpath)
|
||||
if (strlen(regions) > 0)
|
||||
regions = "regions = " + regions
|
||||
info = AddListItem(regions, info, "\r", inf)
|
||||
endif
|
||||
|
||||
return info
|
||||
end
|
||||
|
@ -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 ¶m
|
||||
|
||||
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 ¶m
|
||||
|
||||
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
|
||||
|
32
pearl/preferences/pearl_explorer/attr_filter_pearl.itx
Normal file
32
pearl/preferences/pearl_explorer/attr_filter_pearl.itx
Normal file
@ -0,0 +1,32 @@
|
||||
IGOR
|
||||
WAVES/T attr_filter_summary
|
||||
BEGIN
|
||||
"MonoEnergy"
|
||||
"MonoGrating"
|
||||
"FrontendHSize"
|
||||
"FrontendVSize"
|
||||
"ExitSlit"
|
||||
"ManipulatorTheta"
|
||||
"CenterEnergy"
|
||||
"ManipulatorTilt"
|
||||
"ManipulatorPhi"
|
||||
"AcquisitionMode"
|
||||
"ChannelBegin"
|
||||
"ChannelEnd"
|
||||
"CenterEnergy"
|
||||
"PassEnergy"
|
||||
"NumChannels"
|
||||
"NumFrames"
|
||||
"NumIterations"
|
||||
"StepSize"
|
||||
"NumIterations"
|
||||
"AnalyserSlit"
|
||||
"SampleCurrent"
|
||||
"LensMode"
|
||||
END
|
||||
X SetScale/P x 0,1,"", attr_filter_summary; SetScale y 0,0,"", attr_filter_summary
|
||||
|
||||
WAVES/T attr_filter
|
||||
BEGIN
|
||||
END
|
||||
X SetScale d 0,0,"", attr_filter
|
Reference in New Issue
Block a user