igor 8 compatibility

This commit is contained in:
2019-08-14 17:56:14 +02:00
parent 58135e4f4f
commit 6ab1cefec2
8 changed files with 339 additions and 25 deletions

View File

@ -2,6 +2,7 @@
#pragma IgorVersion = 6.2
#pragma ModuleName = PearlAreaImport
#include <HDF5 Browser>
#include "pearl-compat"
#include "pearl-gui-tools"
// copyright (c) 2013-18 Paul Scherrer Institut
@ -46,7 +47,7 @@ static function BeforeFileOpenHook(refNum,fileName,path,type,creator,kind)
//PathInfo $path
//string FilePath = s_path + filename
string NickName = CleanupName(ParseFilePath(3, FileName, ":", 0, 0), 0)
string NickName = PearlCleanupName(ParseFilePath(3, FileName, ":", 0, 0))
string FileExt = LowerStr(ParseFilePath(4, FileName, ":", 0, 0))
string result = ""
@ -149,7 +150,7 @@ function /s ad_suggest_foldername(filename, [ignoredate,sourcename,unique])
sprintf nickname, "%s_%s_%s", sourcename, datepart, indexpart
endif
else
nickname = CleanupName(basename, 0)
nickname = PearlCleanupName(basename)
endif
if (unique && CheckName(nickname, 11))
@ -1175,6 +1176,243 @@ function /s adh5_test_reduction_func(source, reduction_func, reduction_param, re
return reduction_param
end
/// reduce a three-dimensional intensity distribution
///
/// this function reduces a three-dimensional intensity distribution
/// to a two-dimensional intensity map.
/// the given reduction function is applied once on each Z section.
///
/// @param source source wave.
/// three-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.
///
///
function adh5_reduce_brick(source, reduction_func, reduction_param, result_prefix, [progress, nthreads])
wave source
funcref adh5_default_reduction reduction_func
string reduction_param
string result_prefix
variable progress
variable nthreads
if (ParamIsDefault(progress))
progress = 1
endif
if (ParamIsDefault(nthreads))
nthreads = -1
endif
variable result = 0
// nx and nz are the image dimensions
variable nx, ny, nz, nt
nx = dimsize(source, 0)
ny = dimsize(source, 1)
nz = dimsize(source, 2)
// force 4th dimension to singleton (ad_extract_slab handles 3 dimensions only)
nt = 0
variable nzt = max(nz, 1) * max(nt, 1)
variable izt
// set up multi threading
if (nthreads < 0)
nthreads = ThreadProcessorCount
endif
if (nthreads > 0)
variable threadGroupID = ThreadGroupCreate(nthreads)
variable ithread
for (ithread = 0; ithread < nthreads; ithread += 1)
ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
endfor
else
make /n=(nzt) /df /free processing_folders
endif
if (progress)
display_progress_panel("data reduction", "extracting data (step 1 of 2)...", nzt)
endif
variable iz, it
string dfname
variable iw, nw
string sw
make /n=0 /free /wave result_waves
izt = 0
for (iz = 0; iz < max(nz, 1); iz += 1)
for (it = 0; it < max(nt, 1); it += 1)
dfname = "processing_" + num2str(izt)
newdatafolder /s $dfname
ad_extract_slab(source, nan, nan, nan, nan, iz, iz, "image", pscale=1)
wave image
// send to processing queue
variable /g r_index = iz
variable /g s_index = it
string /g func_param = reduction_param
if (nthreads > 0)
WaveClear image
ThreadGroupPutDF threadGroupID, :
else
processing_folders[izt] = GetDataFolderDFR()
string param = reduction_param
wave /wave reduced_waves = reduction_func(image, param)
variable /g func_result = numpnts(reduced_waves)
adh5_get_result_waves(reduced_waves, "redw_", 0)
WaveClear image, reduced_waves
setdatafolder ::
endif
izt += 1
// progress window
if (progress)
if (update_progress_panel(izt))
result = -4 // user abort
break
endif
endif
endfor
endfor
if (progress)
update_progress_panel(0, message="processing data (step 2 of 2)...")
endif
dfref dfr
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))
result = -4 // user abort
break
endif
endif
while (1)
else
dfr = processing_folders[izt]
if (progress)
if (update_progress_panel(izt))
result = -4 // user abort
break
endif
endif
endif
if (result != 0)
break
endif
nvar rr = dfr:r_index
nvar ss = dfr:s_index
nvar func_result = dfr:func_result
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 /p y dimoffset(source, 2), dimdelta(source, 2), waveunits(source, 2), data
setscale /p z dimoffset(source, 3), dimdelta(source, 3), waveunits(source, 3), 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)
variable tstatus = ThreadGroupRelease(threadGroupID)
if (tstatus == -2)
result = -5 // thread did not terminate properly
endif
else
for (izt = 0; izt < nzt; izt += 1)
KillDataFolder /Z processing_folders[izt]
endfor
endif
if (progress)
kill_progress_panel()
endif
return result
end
/// thread worker for adh5_reduce_brick
///
/// this function polls job data folders from thread group 0
/// and calls the reduction function on their contents.
/// the result waves have prefix "redw_" and are saved in the job folder.
///
threadsafe static function reduce_brick_worker(reduction_func)
funcref adh5_default_reduction reduction_func
do
// wait for job from main thread
do
dfref dfr = ThreadGroupGetDFR(0, 1000)
if (DataFolderRefStatus(dfr) == 0)
if (GetRTError(2))
return 0 // no more jobs
endif
else
break
endif
while (1)
// get input data
wave image = dfr:image
svar func_param = dfr:func_param
nvar rr = dfr:r_index
nvar ss = dfr:s_index
// do the work
newdatafolder /s outDF
variable /g r_index = rr
variable /g s_index = ss
string param = func_param
wave /wave reduced_waves = reduction_func(image, param)
variable /g func_result = numpnts(reduced_waves)
// send output to queue and clean up
adh5_get_result_waves(reduced_waves, "redw_", 0)
WaveClear image, reduced_waves
ThreadGroupPutDF 0, :
KillDataFolder dfr
while (1)
return 0
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.