code changes for release 2.2.0
This commit is contained in:
239
pearl/pearl-scienta-live.ipf
Normal file
239
pearl/pearl-scienta-live.ipf
Normal file
@ -0,0 +1,239 @@
|
||||
#pragma TextEncoding = "UTF-8"
|
||||
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
|
||||
#pragma IgorVersion = 6.35
|
||||
#pragma ModuleName = PearlScientaLive
|
||||
#include "pearl-area-display"
|
||||
|
||||
// Copyright (c) 2019 Paul Scherrer Institut
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
/// @file
|
||||
/// @brief utility functions for operating the Scienta analyser.
|
||||
/// @ingroup ArpesPackage
|
||||
///
|
||||
/// this procedure contains various utility functions for working with the Scienta analyser, e.g.
|
||||
///
|
||||
/// - statistical analysis of true count rates
|
||||
/// - estimate energy and angle resolution
|
||||
///
|
||||
/// @author matthias muntwiler, matthias.muntwiler@psi.ch
|
||||
///
|
||||
/// @copyright 2019 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 PearlScientaLive
|
||||
/// @brief utility functions for operating the Scienta analyser.
|
||||
///
|
||||
/// PearlScientaLive is declared in @ref pearl-scienta-live.ipf.
|
||||
|
||||
/// open live display of most recent scienta measurement
|
||||
///
|
||||
///
|
||||
/// @param epicsname base name of the detector, e.g. X03DA-SCIENTA:
|
||||
/// image1: and cam1: are appended by the function.
|
||||
/// see @ref ad_connect.
|
||||
/// @param nickname nick name under which this detector is referred to in Igor.
|
||||
/// must be a valid data folder name.
|
||||
/// see @ref ad_connect.
|
||||
/// @param wbRGB window background color, e.g. "32768,49152,55296"
|
||||
///
|
||||
function ScientaLiveDisplay(epicsname, nickname, wbRGB)
|
||||
string epicsname
|
||||
string nickname
|
||||
string wbRGB
|
||||
|
||||
ad_connect(epicsname, nickname)
|
||||
string df_name
|
||||
sprintf df_name, "ad_display_profiles(root:pearl_epics:%s)", nickname
|
||||
dfref df = $df_name
|
||||
wave /sdfr=df img = image
|
||||
string graphname = ad_display(img)
|
||||
wbRGB = replacestring("(", wbRGB, "")
|
||||
wbRGB = replacestring(")", wbRGB, "")
|
||||
variable rr = str2num(StringFromList(0, wbRGB, ","))
|
||||
variable gg = str2num(StringFromList(1, wbRGB, ","))
|
||||
variable bb = str2num(StringFromList(2, wbRGB, ","))
|
||||
ModifyGraph /w=$graphname wbRGB=(rr,gg,bb)
|
||||
add_roi_controls()
|
||||
ad_add_overlay(img)
|
||||
end
|
||||
|
||||
#if igorVersion() >= 8
|
||||
/// check exposure and calculate overexposure indicator mask
|
||||
///
|
||||
/// calculate the local count rate density and return a mask
|
||||
/// to indicate where the maximum count rate is exceeded.
|
||||
/// the raw image is filtered by FFT with a gaussian kernel.
|
||||
///
|
||||
/// the raw image must have been acquired in fixed mode.
|
||||
/// slicing and dwell time are accounted for.
|
||||
///
|
||||
/// all intermediate waves are created ad-hoc as free waves.
|
||||
/// this function requires igor 8.
|
||||
///
|
||||
/// @param[i] image raw image from scienta in fixed mode.
|
||||
///
|
||||
/// @param[o] outmask mask wave.
|
||||
/// must have same dimensions as image.
|
||||
/// suggested data type /b/u.
|
||||
/// the mask value in overexposed regions is 0,
|
||||
/// in regular regions 64.
|
||||
///
|
||||
/// @param[i] dwelltime in seconds.
|
||||
///
|
||||
function check_exposure(image, outmask, dwelltime)
|
||||
wave image
|
||||
wave outmask
|
||||
variable dwelltime
|
||||
|
||||
variable xbin = 1
|
||||
variable ybin = 902 / dimsize(image, 1)
|
||||
variable thresh = 1e5 / 900 / 900
|
||||
|
||||
duplicate /free image, filt
|
||||
setscale /p x -dimsize(image, 0)/2, 1, "", filt // energy
|
||||
setscale /p y -dimsize(image, 1)/2, 1, "", filt // angle
|
||||
variable wx = sqrt(500) / xbin
|
||||
variable wy = sqrt(500) / ybin
|
||||
filt = exp(-((x/wx)^2 + (y/wy)^2))
|
||||
variable nfilt = sum(filt)
|
||||
filt /= nfilt
|
||||
fft /free /dest=filt_fft filt
|
||||
|
||||
duplicate /free image, img
|
||||
img /= dwelltime
|
||||
setscale /p x -dimsize(image, 0)/2, 1, "", img
|
||||
setscale /p y -dimsize(image, 1)/2, 1, "", img
|
||||
fft /free /dest=img_fft img
|
||||
img_fft *= filt_fft
|
||||
ifft /free /dest=img_ifft img_fft
|
||||
imagetransform swap img_ifft
|
||||
|
||||
outmask = (img_ifft < thresh) * 64
|
||||
end
|
||||
#endif
|
||||
|
||||
/// optimized check exposure and calculate overexposure indicator mask
|
||||
///
|
||||
/// calculate the local count rate density and return a mask
|
||||
/// to indicate where the maximum count rate is exceeded.
|
||||
/// the raw image is filtered by FFT with a gaussian kernel.
|
||||
///
|
||||
/// the raw image must have been acquired in fixed mode.
|
||||
/// slicing and dwell time are accounted for.
|
||||
///
|
||||
/// this function does the same as check_exposure()
|
||||
/// but keeps intermediate waves for time-optimized processing.
|
||||
/// moreover it is compatible with igor 6.
|
||||
///
|
||||
/// @param[i] image raw image from scienta in fixed mode.
|
||||
///
|
||||
/// @param[o] outmask mask wave.
|
||||
/// must have same dimensions as image.
|
||||
/// suggested data type /b/u.
|
||||
/// the mask value in overexposed regions is 0, in regular regions 64.
|
||||
///
|
||||
/// @param[i] dwelltime in seconds.
|
||||
///
|
||||
/// @param[i] calc_df (optional) data folder reference where intermediate and cached waves should be stored.
|
||||
/// by default, the data folder is named "psc_" plus the name of the image wave
|
||||
/// and inserted in the folder where the image wave is stored.
|
||||
///
|
||||
/// the possible gain can be estimated from the following test data:
|
||||
/// - total execution time 510 ms
|
||||
/// - gain from re-using (but recalculating) waves: 20 ms
|
||||
/// - gain from re-using co_filt_fft: 220 ms
|
||||
///
|
||||
function check_exposure_opt(image, outmask, dwelltime, [calc_df])
|
||||
wave image
|
||||
wave outmask
|
||||
variable dwelltime
|
||||
dfref calc_df
|
||||
|
||||
variable xbin = 1
|
||||
variable ybin = 902 / dimsize(image, 1)
|
||||
variable thresh = 1e5 / 900 / 900
|
||||
|
||||
dfref save_df = GetDataFolderDFR()
|
||||
if (ParamIsDefault(calc_df))
|
||||
dfref source_df = GetWavesDataFolderDFR(image)
|
||||
string calc_df_name = PearlCleanupName("psc_" + NameOfWave(image))
|
||||
dfref calc_df = source_df:$calc_df_name
|
||||
endif
|
||||
NewDataFolder /o /s calc_df
|
||||
|
||||
wave /z co_filt
|
||||
wave /z /c co_filt_fft
|
||||
wave /z co_img
|
||||
wave /z /c co_img_fft
|
||||
wave /z co_img_ifft
|
||||
nvar /z co_img_size_x
|
||||
nvar /z co_img_size_y
|
||||
|
||||
variable cache = 0
|
||||
if (waveexists(co_filt))
|
||||
cache = (dimsize(image, 0) == co_img_size_x) && (dimsize(image, 1) == co_img_size_y)
|
||||
if (!cache)
|
||||
redimension /n=(dimsize(image, 0), dimsize(image, 1)) co_filt, co_filt_fft, co_img, co_img_fft, co_img_ifft
|
||||
endif
|
||||
else
|
||||
duplicate /o image, co_filt, co_img, co_img_ifft
|
||||
make /n=(dimsize(image, 0), dimsize(image, 1)) /c co_filt_fft, co_img_fft
|
||||
variable /g co_img_size_x
|
||||
variable /g co_img_size_y
|
||||
endif
|
||||
|
||||
co_img_size_x = dimsize(image, 0)
|
||||
co_img_size_y = dimsize(image, 1)
|
||||
setscale /p x -co_img_size_x/2, 1, "", co_filt, co_filt_fft, co_img, co_img_fft, co_img_ifft
|
||||
setscale /p y -co_img_size_y/2, 1, "", co_filt, co_filt_fft, co_img, co_img_fft, co_img_ifft
|
||||
|
||||
if (!cache)
|
||||
variable wx = sqrt(500) / xbin
|
||||
variable wy = sqrt(500) / ybin
|
||||
co_filt = exp(-((x/wx)^2 + (y/wy)^2))
|
||||
variable nfilt = sum(co_filt)
|
||||
co_filt /= nfilt
|
||||
fft /dest=co_filt_fft co_filt
|
||||
endif
|
||||
|
||||
co_img /= dwelltime
|
||||
fft /dest=co_img_fft co_img
|
||||
co_img_fft *= co_filt_fft
|
||||
ifft /dest=co_img_ifft co_img_fft
|
||||
imagetransform swap co_img_ifft
|
||||
|
||||
redimension /n=(dimsize(co_img_ifft, 0), dimsize(co_img_ifft, 1)) outmask
|
||||
outmask = (co_img_ifft < thresh) * 64
|
||||
|
||||
SetDataFolder save_df
|
||||
end
|
||||
|
||||
/// calculate the energy resolution of the analyser
|
||||
///
|
||||
/// @param epass pass energy in eV
|
||||
/// @param slit analyser entrance slit in mm
|
||||
///
|
||||
/// @return energy resolution (FWHM)
|
||||
function analyser_energy_resolution(epass, slit)
|
||||
variable epass
|
||||
variable slit
|
||||
|
||||
variable respow
|
||||
if (epass < 4)
|
||||
respow = 1110
|
||||
elseif (epass < 8)
|
||||
respow = 1400
|
||||
else
|
||||
respow = 1750
|
||||
endif
|
||||
|
||||
return epass * max(0.2, slit) / 0.2 / respow
|
||||
end
|
Reference in New Issue
Block a user