PEARL Procedures  rev-distro-2.0.3-0-g0fb0fd9
Igor procedures for the analysis of PEARL data
pearl-area-import.ipf
Go to the documentation of this file.
1 #pragma rtGlobals=3 // Use modern global access method and strict wave access.
2 #pragma IgorVersion = 6.2
3 #pragma ModuleName = PearlAreaImport
4 #include <HDF5 Browser>
5 #include "pearl-gui-tools"
6 
7 // copyright (c) 2013-18 Paul Scherrer Institut
8 //
9 // Licensed under the Apache License, Version 2.0 (the "License");
10 // you may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at
12 // http:///www.apache.org/licenses/LICENSE-2.0
13 
33 
38 
41 static function BeforeFileOpenHook(refNum,fileName,path,type,creator,kind)
42  variable refNum, kind
43  string fileName, path, type, creator
44 
45  variable handledOpen = 0
46 
47  //PathInfo $path
48  //string FilePath = s_path + filename
49  string NickName = CleanupName(ParseFilePath(3, FileName, ":", 0, 0), 0)
50  string FileExt = LowerStr(ParseFilePath(4, FileName, ":", 0, 0))
51  string result = ""
52 
53  // override nickname with custom setting
54  svar /z cnn = gsCustomNickName
55  if (svar_exists(cnn))
56  if (exists("gvNickNameIndex") != 2)
57  variable/g gvNickNameIndex = 1
58  endif
59  nvar nni = gvNickNameIndex
60  NickName = cnn + num2str(nni)
61  nni += 1
62  endif
63 
64  if (stringmatch(FileExt, "h5") == 1)
65  result = adh5_load_complete(NickName, path, FileName)
66  endif
67 
68  string/g s_latest_datafile = result
69  string/g s_latest_nickname = nickname
70 
71  handledOpen = strlen(result) > 0
72  if (handledOpen)
73  close refnum
74  endif
75 
76  return handledOpen // 1 tells Igor not to open the file
77 End
78 
105 function /s ad_suggest_foldername(filename, [ignoredate,sourcename,unique])
106  string filename
107  variable ignoredate
108  string sourcename
109  variable unique
110 
111  if (ParamIsDefault(ignoredate))
112  ignoredate = 0
113  endif
114  if (ParamIsDefault(unique))
115  unique = 0
116  endif
117 
118  string basename = ParseFilePath(3, filename, ":", 0, 0)
119  string extension = ParseFilePath(4, filename, ":", 0, 0)
120  string nickname
121 
122  string autosource
123  if (strsearch(basename, "scienta", 0, 2) >= 0)
124  autosource = "sci"
125  elseif (strsearch(basename, "pshell", 0, 2) >= 0)
126  autosource = "psh"
127  elseif (strsearch(basename, "OP-SL", 0, 2) >= 0)
128  autosource = "sl"
129  elseif (strsearch(basename, "ES-PS", 0, 2) >= 0)
130  autosource = "es"
131  else
132  autosource = "xy"
133  endif
134  if (ParamIsDefault(sourcename))
135  sourcename = autosource
136  endif
137 
138  variable nparts = ItemsInList(basename, "-")
139  if (nparts >= 3)
140  string datepart = StringFromList(1, basename, "-")
141  variable l_datepart = strlen(datepart)
142  if (l_datepart == 8)
143  datepart = datepart[l_datepart-6, l_datepart-1]
144  endif
145  string indexpart = StringFromList(2, basename, "-")
146  if (ignoredate)
147  sprintf nickname, "%s_%s", sourcename, indexpart
148  else
149  sprintf nickname, "%s_%s_%s", sourcename, datepart, indexpart
150  endif
151  else
152  nickname = CleanupName(basename, 0)
153  endif
154 
155  if (unique && CheckName(nickname, 11))
156  nickname = UniqueName(nickname + "_", 11, 0)
157  endif
158 
159  return nickname
160 end
161 
166 function ad_load_dialog(APathName)
167  string APathName
168 
169  variable refNum
170  string message = "Select data files"
171  string filepaths
172  string filefilters = "Area Detector HDF5 Files (*.h5):.h5;"
173  filefilters += "All Files:.*;"
174 
175  PathInfo /S $APathName
176  Open /D /R /F=filefilters /M=message /MULT=1 refNum
177  filepaths = S_fileName
178 
179  dfref saveDF = GetDataFolderDFR()
180  setdatafolder root:
181 
182  if (strlen(filepaths) > 0)
183  variable nfiles = ItemsInList(filepaths, "\r")
184  variable ifile
185  for(ifile = 0; ifile < nfiles; ifile += 1)
186  String path = StringFromList(ifile, filepaths, "\r")
187  string nickname = ad_suggest_foldername(path)
188  adh5_load_complete(nickname, "", path)
189  endfor
190  endif
191 
192  setdatafolder saveDF
193 end
194 
206 function /s adh5_load_complete(ANickName, APathName, AFileName, [load_data, load_attr])
207  string ANickName
208  string APathName
209  string AFileName
210  variable load_data
211  variable load_attr
212 
213  if (ParamIsDefault(load_data))
214  load_data = 1
215  endif
216  if (ParamIsDefault(load_attr))
217  load_attr = 1
218  endif
219 
220  dfref saveDF = GetDataFolderDFR()
221  setdatafolder root:
222  newdatafolder /s/o $("root:" + ANickName)
223 
224  // open file
225  variable fileID
226  string instrumentpath = "/entry/instrument/"
227  string detectorpath = instrumentpath + "detector/"
228  string attributespath = instrumentpath + "NDAttributes/"
229  string datasetname
230  string datawavename
231 
232  // performance monitoring
233  variable timerRefNum
234  variable /g adh5_perf_secs
235  timerRefNum = startMSTimer
236 
237  // avoid compilation error if HDF5 XOP has not been loaded
238  #if Exists("HDF5OpenFile")
239  HDF5OpenFile /P=$APathName/R fileID as AFileName
240  if (v_flag == 0)
241  AFileName = s_path + s_filename
242  print "loading " + s_filename + "\r"
243 
244  if (load_data)
245  adh5_load_detector_slabs(fileID, detectorpath)
246  endif
247  if (load_attr)
248  newdatafolder /o/s attr
249  adh5_loadattr_all(fileID, attributespath)
250  setdatafolder ::
251  endif
252 
253  wave /z data
254  if (waveexists(data))
255  //adh5_redim(data) // not to be used with adh5_load_detector_slabs
256  adh5_scale(data)
257  endif
258 
259  HDF5CloseFile fileID
260  else
261  AFileName = ""
262  endif
263  #else
264  Abort "HDF5 XOP not loaded."
265  #endif
266 
267  if (timerRefNum >= 0)
268  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
269  endif
270 
271  setdatafolder saveDF
272  return AFileName
273 end
274 
301 function /s adh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [load_data, load_attr, progress])
302  string ANickName
303  string APathName
304  string AFileName
305 
306  funcref adh5_default_reduction reduction_func
307  string reduction_param
308 
309  variable load_data
310  variable load_attr
311  variable progress
312 
313  if (ParamIsDefault(load_data))
314  load_data = 1
315  endif
316  if (ParamIsDefault(load_attr))
317  load_attr = 1
318  endif
319  if (ParamIsDefault(progress))
320  progress = 1
321  endif
322 
323  dfref saveDF = GetDataFolderDFR()
324  setdatafolder root:
325  newdatafolder /s/o $("root:" + ANickName)
326 
327  // open file
328  variable fileID
329  string instrumentpath = "/entry/instrument/"
330  string detectorpath = instrumentpath + "detector/"
331  string attributespath = instrumentpath + "NDAttributes/"
332  string datasetname
333  string datawavename
334 
335  // performance monitoring
336  variable timerRefNum
337  variable /g adh5_perf_secs
338  timerRefNum = startMSTimer
339 
340  // avoid compilation error if HDF5 XOP has not been loaded
341  #if Exists("HDF5OpenFile")
342  HDF5OpenFile /P=$APathName/R fileID as AFileName
343  if (v_flag == 0)
344  AFileName = s_path + s_filename
345  print "loading " + s_filename + "\r"
346 
347  if (load_attr)
348  newdatafolder /o/s attr
349  adh5_loadattr_all(fileID, attributespath)
350  setdatafolder ::
351  endif
352  if (load_data)
353  adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduction_param, progress=progress)
354  endif
355 
356  HDF5CloseFile fileID
357  else
358  AFileName = ""
359  endif
360  #else
361  Abort "HDF5 XOP not loaded."
362  #endif
363 
364  if (timerRefNum >= 0)
365  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
366  endif
367 
368  setdatafolder saveDF
369  return AFileName
370 end
371 
386 function /s adh5_load_preview(ANickName, APathName, AFileName, [load_data, load_attr])
387  string ANickName
388  string APathName
389  string AFileName
390  variable load_data
391  variable load_attr
392 
393  if (ParamIsDefault(load_data))
394  load_data = 1
395  endif
396  if (ParamIsDefault(load_attr))
397  load_attr = 1
398  endif
399 
400  dfref saveDF = GetDataFolderDFR()
401  setdatafolder root:
402  newdatafolder /o/s pearl_area
403  newdatafolder /o/s preview
404 
405  // open file
406  variable fileID
407  string instrumentpath = "/entry/instrument/"
408  string detectorpath = instrumentpath + "detector/"
409  string attributespath = instrumentpath + "NDAttributes/"
410  string datasetname
411  string datawavename
412 
413  // performance monitoring
414  variable timerRefNum
415  variable /g adh5_perf_secs
416  timerRefNum = startMSTimer
417 
418  // avoid compilation error if HDF5 XOP has not been loaded
419  #if Exists("HDF5OpenFile")
420  HDF5OpenFile /P=$APathName/R/Z fileID as AFileName
421  if (v_flag == 0)
422  AFileName = s_path + s_filename
423 
424  // detector data
425  datasetname = detectorpath + "data"
426  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
427  InitHDF5DataInfo(di)
428  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
429  if (err != 0)
430  print "error accessing detector/data"
431  return ""
432  endif
433  if (di.ndims < 2)
434  print "error: rank of dataset < 2"
435  return ""
436  endif
437 
438  variable dim2start = 0, dim2count = 1, dim3start = 0, dim3count = 1
439  if (di.ndims >= 3)
440  dim2start = floor(di.dims[di.ndims - 3] / 2)
441  dim2count = 1
442  endif
443  if (di.ndims >= 4)
444  dim3start = floor(di.dims[di.ndims - 4] / 2)
445  dim3count = 1
446  endif
447 
448  if (load_data)
449  adh5_load_detector_image(fileID, detectorpath, dim2start, dim2count, dim3start, dim3count)
450  wave /z data
451  string destpath = GetDataFolder(1, saveDF) + ANickName
452  if (waveexists(data))
453  duplicate /o data, $destpath
454  wave /z data = $destpath
455  endif
456  endif
457 
458  if (load_attr)
459  setdatafolder saveDF
460  newdatafolder /o/s attr
461  killwaves /a/z
462  adh5_loadattr_all(fileID, attributespath)
463  setdatafolder ::
464  if (waveexists(data))
465  adh5_scale(data)
466  endif
467  endif
468 
469  HDF5CloseFile fileID
470  else
471  print "error opening file " + AFileName
472  AFileName = ""
473  endif
474  #else
475  Abort "HDF5 XOP not loaded."
476  #endif
477 
478  if (timerRefNum >= 0)
479  adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
480  endif
481 
482  setdatafolder saveDF
483  return AFileName
484 end
485 
496 function /s adh5_load_info(APathName, AFileName)
497  string APathName
498  string AFileName
499 
500  dfref saveDF = GetDataFolderDFR()
501 
502  // open file
503  variable fileID
504  string instrumentpath = "/entry/instrument/"
505  string detectorpath = instrumentpath + "detector/"
506  string attributespath = instrumentpath + "NDAttributes/"
507  string datasetname
508  string datawavename
509 
510  string s_info = ""
511  string s
512 
513  variable idim
514 
515  // avoid compilation error if HDF5 XOP has not been loaded
516  #if Exists("HDF5OpenFile")
517  HDF5OpenFile /P=$APathName/R/Z fileID as AFileName
518  if (v_flag == 0)
519  AFileName = s_path + s_filename
520 
521  // detector data
522  datasetname = detectorpath + "data"
523  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
524  InitHDF5DataInfo(di)
525  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
526  if (err != 0)
527  print "error accessing detector/data"
528  return ""
529  endif
530 
531  for (idim = 0; idim < di.ndims; idim += 1)
532  sprintf s, "dim %u: %u points", idim, di.dims[idim]
533  if (strlen(s_info) > 0)
534  s_info = s_info + "\r" + s
535  else
536  s_info = s
537  endif
538  endfor
539 
540  dfref df = NewFreeDataFolder()
541  setdatafolder df
542  adh5_loadattr_all(fileID, attributespath)
543 
544  for (idim = 1; idim < 5; idim += 1)
545  sprintf s, "Scan%uActive", idim
546  wave /z w = $s
547  if (waveexists(w) && (numpnts(w) > 0) && (w[0] > 0))
548  sprintf s, "Scan%uPositioner1", idim
549  wave /t wt = $s
550  sprintf s, "scan %u: %s", idim, wt[0]
551  if (strlen(s_info) > 0)
552  s_info = s_info + "\r" + s
553  else
554  s_info = s
555  endif
556  endif
557  endfor
558 
559  HDF5CloseFile fileID
560  else
561  print "error opening file " + AFileName
562  AFileName = ""
563  endif
564  #else
565  Abort "HDF5 XOP not loaded."
566  #endif
567 
568  setdatafolder saveDF
569  return s_info
570 end
571 
580 function adh5_load_detector(fileID, detectorpath)
581  variable fileID
582  string detectorpath
583 
584  // avoid compilation error if HDF5 XOP has not been loaded
585  #if Exists("HDF5LoadData")
586  string datasetname
587  string datawavename
588 
589  // detector data
590  datasetname = detectorpath + "data"
591  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
592  InitHDF5DataInfo(di)
593  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
594  if (err != 0)
595  print "error accessing detector/data"
596  return -1
597  endif
598  if (di.ndims < 2)
599  print "error: rank of dataset < 2"
600  return -2
601  endif
602 
603  HDF5LoadData /O /Q /Z fileID, datasetname
604  wave data
605 
606  #else
607  Abort "HDF5 XOP not loaded."
608  #endif
609 end
610 
625 function adh5_redim(data)
626  wave data
627 
628  duplicate /free data, tempdata
629  variable nd = wavedims(tempdata)
630  variable nx = dimsize(tempdata, nd - 1)
631  variable ny = dimsize(tempdata, nd - 2)
632  variable nz = dimsize(tempdata, nd - 3)
633  variable nt = dimsize(tempdata, nd - 4)
634 
635  switch (nd)
636  case 2:
637  if (nx <= 1)
638  redimension /n=(ny) data
639  setdimlabel 0, -1, AD_Dim1, data
640  data = tempdata[p][0]
641  elseif (ny <= 1)
642  redimension /n=(nx) data
643  setdimlabel 0, -1, AD_Dim0, data
644  data = tempdata[0][p]
645  else
646  redimension /n=(nx,ny) data
647  setdimlabel 0, -1, AD_Dim0, data
648  setdimlabel 1, -1, AD_Dim1, data
649  data = tempdata[q][p]
650  endif
651  break
652  case 3:
653  if (nx <= 1)
654  redimension /n=(ny,nz) data
655  setdimlabel 0, -1, AD_Dim1, data
656  setdimlabel 1, -1, AD_DimN, data
657  multithread data = tempdata[q][p][0]
658  elseif (ny <= 1)
659  redimension /n=(nx,nz) data
660  setdimlabel 0, -1, AD_Dim0, data
661  setdimlabel 1, -1, AD_DimN, data
662  multithread data = tempdata[q][0][p]
663  elseif (nz <= 1)
664  redimension /n=(nx,ny) data
665  setdimlabel 0, -1, AD_Dim0, data
666  setdimlabel 1, -1, AD_Dim1, data
667  multithread data = tempdata[0][q][p]
668  else
669  redimension /n=(nx,ny,nz) data
670  setdimlabel 0, -1, AD_Dim0, data
671  setdimlabel 1, -1, AD_Dim1, data
672  setdimlabel 2, -1, AD_DimN, data
673  multithread data = tempdata[r][q][p]
674  endif
675  break
676  case 4:
677  if (nz <= 1)
678  // singleton "frame number" dimension
679  redimension /n=(nx,ny,nt) data
680  setdimlabel 0, -1, AD_Dim0, data
681  setdimlabel 1, -1, AD_Dim1, data
682  setdimlabel 2, -1, AD_DimX, data
683  multithread data = tempdata[r][0][q][p]
684  else
685  redimension /n=(nx,ny,nz,nt) data
686  setdimlabel 0, -1, AD_Dim0, data
687  setdimlabel 1, -1, AD_Dim1, data
688  setdimlabel 2, -1, AD_DimN, data
689  setdimlabel 3, -1, AD_DimX, data
690  multithread data = tempdata[s][r][q][p]
691  endif
692  break
693  endswitch
694 end
695 
706 static function /DF GetAttrDataFolderDFR(data)
707  wave data
708 
709  dfref dataDF = GetWavesDataFolderDFR(data)
710  dfref attrDF = dataDF:attr
711  if (DataFolderRefStatus(attrDF) == 0)
712  attrDF = dataDF
713  endif
714 
715  return attrDF
716 end
717 
725 function adh5_scale(data,[source])
726  wave data
727  string source
728 
729  dfref saveDF = GetDataFolderDFR()
730  dfref dataDF = GetWavesDataFolderDFR(data)
731  dfref attrDF = GetAttrDataFolderDFR(data)
732 
733  if (ParamIsDefault(source))
734  // is the source a Scienta analyser?
735  wave /SDFR=attrDF /Z AcquisitionMode
736  wave /SDFR=attrDF /T /Z Manufacturer
737  source = "unknown"
738  if (waveexists(Manufacturer) && (numpnts(Manufacturer) >= 1))
739  strswitch(Manufacturer[0])
740  case "VG Scienta":
741  source = "scienta"
742  break
743  case "Prosilica":
744  source = "prosilica"
745  break
746  endswitch
747  elseif (waveexists(AcquisitionMode) && (numpnts(AcquisitionMode) >= 1))
748  if (stringmatch(note(AcquisitionMode), "*SCIENTA*"))
749  source = "scienta"
750  endif
751  endif
752  endif
753 
754  strswitch(source)
755  case "prosilica":
756  // pixel scale - nothing to do
757  break
758  case "scienta":
759  adh5_scale_scienta(data)
760  break
761  endswitch
762 
763  setdatafolder saveDF
764 end
765 
779 function adh5_load_detector_slabs(fileID, detectorpath, [progress])
780  variable fileID
781  string detectorpath
782  variable progress
783 
784  if (ParamIsDefault(progress))
785  progress = 1
786  endif
787  variable result = 0
788 
789  // avoid compilation error if HDF5 XOP has not been loaded
790  #if Exists("HDF5LoadData")
791  string datasetname
792  string datawavename
793 
794  // detector data
795  datasetname = detectorpath + "data"
796  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
797  InitHDF5DataInfo(di)
798  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
799  if (err != 0)
800  print "error accessing detector/data"
801  return -1
802  endif
803  if (di.ndims < 2)
804  print "error: rank of dataset < 2"
805  return -2
806  endif
807 
808  // nx and nz are the image dimensions
809  variable idx, idy, idz, idt, izt
810  idx = di.ndims - 1
811  idy = di.ndims - 2
812  idz = -1
813  idt = -1
814 
815  variable nx, ny, nz, nt, nzt
816  nx = di.dims[idx]
817  ny = di.dims[idy]
818  nz = 1
819  nt = 1
820 
821  make /n=(nx,ny,nz,nt) /o data
822  string dim_labels = "AD_Dim0;AD_Dim1;AD_DimN;AD_DimX;AD_DimY"
823  string dim_label
824  dim_label = StringFromList(0, dim_labels, ";")
825  setdimlabel 0, -1, $dim_label, data
826  dim_labels = RemoveFromList(dim_label, dim_labels, ";")
827  dim_label = StringFromList(0, dim_labels, ";")
828  setdimlabel 1, -1, $dim_label, data
829  dim_labels = RemoveFromList(dim_label, dim_labels, ";")
830 
831  // find additional dimensions, ignore singletons
832  variable id
833  for (id = idy - 1; (id >= 0) && (nz == 1); id -= 1)
834  if (di.dims[id] > 1)
835  idz = id
836  nz = di.dims[id]
837  dim_label = StringFromList(0, dim_labels, ";")
838  setdimlabel 2, -1, $dim_label, data
839  endif
840  dim_labels = RemoveListItem(0, dim_labels, ";")
841  endfor
842  for (id = idz - 1; (id >= 0) && (nt == 1); id -= 1)
843  if (di.dims[id] > 1)
844  idt = id
845  nt = di.dims[id]
846  dim_label = StringFromList(0, dim_labels, ";")
847  setdimlabel 3, -1, $dim_label, data
848  endif
849  dim_labels = RemoveListItem(0, dim_labels, ";")
850  endfor
851  redimension /n=(nx,ny,nz,nt) data
852 
853  // default values if dimensions are not present in dataset
854  if (idz < 0)
855  idz = idx + 1
856  idt = idz + 1
857  elseif (idt < 0)
858  idt = idx + 1
859  endif
860 
861  nzt = nz * nt
862  izt = 0
863  if (progress)
864  display_progress_panel("HDF5 Import", "Loading data...", nzt)
865  endif
866 
867  // load data image by image
868  HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
869  wave slab
870  slab[][%Start] = 0
871  slab[][%Stride] = 1
872  slab[][%Count] = 1
873  slab[][%Block] = 1
874  slab[idx][%Block] = nx
875  slab[idy][%Block] = ny
876 
877  variable iz, it
878  for (iz = 0; iz < nz; iz += 1)
879  for (it = 0; it < nt; it += 1)
880  slab[idz][%Start] = iz
881  slab[idt][%Start] = it
882  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetname
883  wave slabdata // 2D, 3D, or 4D with singletons
884  switch (WaveDims(slabdata))
885  case 2:
886  data[][][iz][it] = slabdata[q][p]
887  break
888  case 3:
889  data[][][iz][it] = slabdata[0][q][p]
890  break
891  case 4:
892  data[][][iz][it] = slabdata[0][0][q][p]
893  break
894  endswitch
895  // progress window
896  izt += 1
897  if (progress)
898  if (update_progress_panel(izt))
899  result = -4 // user abort
900  break
901  endif
902  endif
903  endfor
904  if (result < 0)
905  break
906  endif
907  endfor
908 
909  if (nz == 1)
910  redimension /n=(nx,ny) data
911  elseif (nt == 1)
912  redimension /n=(nx,ny,nz) data
913  endif
914 
915  if (progress)
917  endif
918  #else
919  Abort "HDF5 XOP not loaded."
920  #endif
921 
922  return result
923 end
924 
944 function adh5_load_detector_image(fileID, detectorpath, dim2start, dim2count, dim3start, dim3count)
945  variable fileID
946  string detectorpath
947  variable dim2start
948  variable dim2count
949  variable dim3start
950  variable dim3count
951 
952  // avoid compilation error if HDF5 XOP has not been loaded
953  #if Exists("HDF5LoadData")
954  string datasetname
955  string datawavename
956 
957  // detector data
958  datasetname = detectorpath + "data"
959  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
960  InitHDF5DataInfo(di)
961  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
962  if (err != 0)
963  print "error accessing detector/data"
964  return -1
965  endif
966  if (di.ndims < 1)
967  print "error: rank of dataset < 1"
968  return -2
969  endif
970 
971  // nx and nz are the image dimensions
972  variable idx, idy, idz, idt
973  idx = di.ndims - 1
974  idy = di.ndims >= 2 ? di.ndims - 2 : 1
975  idz = di.ndims >= 3 ? di.ndims - 3 : 2
976  idt = di.ndims >= 4 ? di.ndims - 4 : 3
977 
978  variable nx, ny
979  nx = di.dims[idx]
980  ny = di.ndims >= 2 ? di.dims[idy] : 1
981 
982  variable dim2end = dim2start + dim2count - 1
983  variable dim3end = dim3start + dim3count - 1
984 
985  // the slab wave is at least 4-dimensional
986  // it will also load lower-dimensional datasets
987  HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
988  wave slab
989  slab[][%Start] = 0
990  slab[][%Stride] = 1
991  slab[][%Count] = 1
992  slab[][%Block] = 1
993  slab[idx][%Block] = nx
994  slab[idy][%Block] = ny
995 
996  make /n=(nx,ny)/o/d data
997  data = 0
998  variable iz, it
999  variable navg = 0
1000  for (iz = dim2start; iz <= dim2end; iz += 1)
1001  for (it = dim3start; it <= dim3end; it += 1)
1002  slab[idz][%Start] = iz
1003  slab[idt][%Start] = it
1004  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetname
1005  wave slabdata // 2D, 3D, or 4D with singletons
1006  switch (WaveDims(slabdata))
1007  case 1:
1008  data += slabdata[p]
1009  navg += 1
1010  break
1011  case 2:
1012  data += slabdata[q][p]
1013  navg += 1
1014  break
1015  case 3:
1016  data += slabdata[0][q][p]
1017  navg += 1
1018  break
1019  case 4:
1020  data += slabdata[0][0][q][p]
1021  navg += 1
1022  break
1023  endswitch
1024  endfor
1025  endfor
1026  data /= navg
1027  setdimlabel 0, -1, AD_Dim0, data
1028  setdimlabel 1, -1, AD_Dim1, data
1029 
1030  #else
1031  Abort "HDF5 XOP not loaded."
1032  #endif
1033 end
1034 
1041  string all_funcs = FunctionList("*", ";", "KIND:6,NPARAMS:2,VALTYPE:8")
1042  string result = ""
1043 
1044  variable ii
1045  variable nn = ItemsInList(all_funcs, ";")
1046 
1047  string funcname
1048  string info
1049  variable nparams
1050  variable accept
1051 
1052  for (ii = 0; ii < nn; ii += 1)
1053  funcname = StringFromList(ii, all_funcs, ";")
1054  info = FunctionInfo(funcname)
1055  accept = (NumberByKey("RETURNTYPE", info, ":", ";") == 0x4000)
1056  accept = accept && (cmpstr(StringByKey("THREADSAFE", info, ":", ";"), "yes") == 0)
1057  accept = accept && (NumberByKey("N_PARAMS", info, ":", ";") == 2)
1058  accept = accept && (NumberByKey("N_OPT_PARAMS", info, ":", ";") == 0)
1059  if (accept)
1060  // one numeric wave and one pass-by-reference string
1061  accept = accept && (NumberByKey("PARAM_0_TYPE", info, ":", ";") == 0x4002)
1062  accept = accept && (NumberByKey("PARAM_1_TYPE", info, ":", ";") == 0x3000)
1063  endif
1064  if (accept)
1065  result = AddListItem(funcname, result, ";")
1066  endif
1067  endfor
1068 
1069  result = SortList(result, ";", 4)
1070  return result
1071 end
1072 
1110 threadsafe function /wave adh5_default_reduction(source, param)
1111  wave source
1112  string &param
1113 
1114  // demo code
1115  // integrate along the dimensions
1116  make /n=0 /free dest1, dest2
1117  adh5_setup_profile(source, dest1, 0)
1118  ad_profile_x_w(source, 0, -1, dest1)
1119  adh5_setup_profile(source, dest2, 1)
1120  ad_profile_y_w(source, 0, -1, dest2)
1121 
1122  make /n=2 /free /wave results
1123  results[0] = dest1
1124  results[1] = dest2
1125  return results
1126 end
1127 
1133 threadsafe function adh5_setup_profile(image, profile, dim)
1134  wave image // prototype
1135  wave profile // destination wave
1136  variable dim // which dimension to keep: 0 = X, 1 = Y
1137 
1138  redimension /n=(dimsize(image, dim)) profile
1139  setscale /p x dimoffset(image, dim), dimdelta(image, dim), waveunits(image, dim), profile
1140  setscale d 0, 0, waveunits(image, -1), profile
1141  setdimlabel 0, -1, $getdimlabel(image, dim, -1), profile
1142 end
1143 
1166 function /s adh5_test_reduction_func(source, reduction_func, reduction_param, result_prefix)
1167  wave source
1168  funcref adh5_default_reduction reduction_func
1169  string reduction_param
1170  string result_prefix
1171 
1172  wave /wave results = reduction_func(source, reduction_param)
1173  adh5_get_result_waves(results, result_prefix, 1)
1174 
1175  return reduction_param
1176 end
1177 
1192 threadsafe function adh5_get_result_waves(results, result_prefix, start_index)
1193  wave /wave results
1194  string result_prefix
1195  variable start_index
1196 
1197  variable nw = numpnts(results)
1198  variable iw
1199  string sw
1200  for (iw = 0; iw < nw; iw += 1)
1201  sw = result_prefix + num2str(iw + start_index)
1202  duplicate /o results[iw], $sw
1203  endfor
1204 end
1205 
1228 function adh5_load_reduced_detector(fileID, detectorpath, reduction_func, reduction_param, [progress, nthreads])
1229  variable fileID
1230  string detectorpath
1231  funcref adh5_default_reduction reduction_func
1232  string reduction_param
1233  variable progress
1234  variable nthreads
1235 
1236  if (ParamIsDefault(progress))
1237  progress = 1
1238  endif
1239  if (ParamIsDefault(nthreads))
1240  nthreads = -1
1241  endif
1242  variable result = 0
1243 
1244  // avoid compilation error if HDF5 XOP has not been loaded
1245  #if Exists("HDF5LoadData")
1246  string datasetname
1247  string datawavename
1248 
1249  // detector data
1250  datasetname = detectorpath + "data"
1251  STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
1252  InitHDF5DataInfo(di)
1253  variable err = HDF5DatasetInfo(fileID, datasetname, 0, di)
1254  if (err != 0)
1255  print "error accessing detector/data"
1256  return -1
1257  endif
1258  if (di.ndims < 2)
1259  print "error: rank of dataset < 2"
1260  return -2
1261  endif
1262 
1263  // nx and nz are the image dimensions
1264  variable idx, idy, idz, idt
1265  idx = di.ndims - 1
1266  idy = di.ndims - 2
1267  idz = -1
1268  idt = -1
1269 
1270  variable nx, ny, nz, nt
1271  nx = di.dims[idx]
1272  ny = di.dims[idy]
1273  nz = 1
1274  nt = 1
1275 
1276  // find additional dimensions, ignore singletons
1277  variable id
1278  for (id = idy - 1; (id >= 0) && (nz == 1); id -= 1)
1279  if (di.dims[id] > 1)
1280  idz = id
1281  nz = di.dims[id]
1282  endif
1283  endfor
1284  for (id = idz - 1; (id >= 0) && (nt == 1); id -= 1)
1285  if (di.dims[id] > 1)
1286  idt = id
1287  nt = di.dims[id]
1288  endif
1289  endfor
1290  // default values if dimensions are not present in dataset
1291  if (idz < 0)
1292  idz = idx + 1
1293  idt = idz + 1
1294  elseif (idt < 0)
1295  idt = idx + 1
1296  endif
1297  variable nzt = nz * nt
1298  variable izt
1299 
1300  // load data image by image
1301  HDF5MakeHyperslabWave(GetDataFolder(1) + "slab", max(di.ndims, 4))
1302  wave slab
1303  slab[][%Start] = 0
1304  slab[][%Stride] = 1
1305  slab[][%Count] = 1
1306  slab[][%Block] = 1
1307  slab[idx][%Block] = nx
1308  slab[idy][%Block] = ny
1309 
1310  // set up multi threading
1311  if (nthreads < 0)
1312  nthreads = ThreadProcessorCount
1313  endif
1314  if (nthreads > 0)
1315  variable threadGroupID = ThreadGroupCreate(nthreads)
1316  variable ithread
1317  for (ithread = 0; ithread < nthreads; ithread += 1)
1318  ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
1319  endfor
1320  else
1321  make /n=(nzt) /df /free processing_folders
1322  endif
1323 
1324  if (progress)
1325  display_progress_panel("HDF5 Import", "Loading data (step 1 of 2)...", nzt)
1326  endif
1327 
1328  make /n=(nx,ny)/d image_template
1329  setdimlabel 0, -1, AD_Dim0, image_template
1330  setdimlabel 1, -1, AD_Dim1, image_template
1331  adh5_scale(image_template)
1332 
1333  variable iz, it
1334  string dfname
1335  variable iw, nw
1336  string sw
1337  make /n=0 /free /wave result_waves
1338 
1339  izt = 0
1340  for (iz = 0; iz < nz; iz += 1)
1341  for (it = 0; it < nt; it += 1)
1342  // load hyperslab
1343  slab[idz][%Start] = iz
1344  slab[idt][%Start] = it
1345  dfname = "processing_" + num2str(izt)
1346  newdatafolder /s $dfname
1347  HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetname
1348 
1349  // send to processing queue
1350  duplicate image_template, image
1351  variable /g r_index = iz
1352  variable /g s_index = it
1353  string /g func_param = reduction_param
1354 
1355  if (nthreads > 0)
1356  WaveClear image
1357  ThreadGroupPutDF threadGroupID, :
1358  else
1359  processing_folders[izt] = GetDataFolderDFR()
1360  wave slabdata
1361  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
1362  variable /g func_result = numpnts(reduced_waves)
1363  adh5_get_result_waves(reduced_waves, "redw_", 0)
1364  WaveClear slabdata, image, reduced_waves
1365  setdatafolder ::
1366  endif
1367 
1368  izt += 1
1369  // progress window
1370  if (progress)
1371  if (update_progress_panel(izt))
1372  result = -4 // user abort
1373  break
1374  endif
1375  endif
1376  endfor
1377  endfor
1378 
1379  killwaves /z slab, image_template
1380  if (progress)
1381  update_progress_panel(0, message="Processing data (step 2 of 2)...")
1382  endif
1383 
1384  dfref dfr
1385  for (izt = 0; (izt < nzt) && (result == 0); izt += 1)
1386  if (nthreads > 0)
1387  do
1388  dfr = ThreadGroupGetDFR(threadGroupID, 1000)
1389  if (DatafolderRefStatus(dfr) != 0)
1390  break
1391  endif
1392  if (progress)
1393  if (update_progress_panel(izt))
1394  result = -4 // user abort
1395  break
1396  endif
1397  endif
1398  while (1)
1399  else
1400  dfr = processing_folders[izt]
1401  if (progress)
1402  if (update_progress_panel(izt))
1403  result = -4 // user abort
1404  break
1405  endif
1406  endif
1407  endif
1408 
1409  if (result != 0)
1410  break
1411  endif
1412 
1413  nvar rr = dfr:r_index
1414  nvar ss = dfr:s_index
1415  nvar func_result = dfr:func_result
1416 
1417  if (func_result < 1)
1418  result = -3 // dimension reduction error
1419  break
1420  endif
1421 
1422  if (numpnts(result_waves) == 0)
1423  redimension /n=(func_result) result_waves
1424  for (iw = 0; iw < func_result; iw += 1)
1425  sw = "redw_" + num2str(iw)
1426  wave profile = dfr:$sw
1427  sw = "ReducedData" + num2str(iw+1)
1428  make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
1429  wave data = $sw
1430  setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
1431  setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
1432  setscale d 0, 0, waveunits(profile, -1), data
1433  result_waves[iw] = data
1434  endfor
1435  endif
1436  for (iw = 0; iw < func_result; iw += 1)
1437  sw = "redw_" + num2str(iw)
1438  wave profile = dfr:$sw
1439  wave data = result_waves[iw]
1440  data[][rr][ss] = profile[p]
1441  endfor
1442  endfor
1443 
1444  if (nthreads > 0)
1445  variable tstatus = ThreadGroupRelease(threadGroupID)
1446  if (tstatus == -2)
1447  result = -5 // thread did not terminate properly
1448  endif
1449  else
1450  for (izt = 0; izt < nzt; izt += 1)
1451  KillDataFolder /Z processing_folders[izt]
1452  endfor
1453  endif
1454 
1455  if (result == 0)
1456  nw = numpnts(result_waves)
1457  for (iw = 0; iw < nw; iw += 1)
1458  wave data = result_waves[iw]
1459  if (nz == 1)
1460  redimension /n=(dimsize(data, 0)) data
1461  elseif (nt == 1)
1462  redimension /n=(dimsize(data, 0),nz) data
1463  setdimlabel 1, -1, AD_DimN, data
1464  else
1465  setdimlabel 1, -1, AD_DimN, data
1466  setdimlabel 2, -1, AD_DimX, data
1467  endif
1468  endfor
1469  endif
1470  if (progress)
1472  endif
1473 
1474  #else
1475  Abort "HDF5 XOP not loaded."
1476  #endif
1477  return result
1478 end
1479 
1480 threadsafe static function reduce_slab_worker(reduction_func)
1481  funcref adh5_default_reduction reduction_func
1482  do
1483  // wait for job from main thread
1484  do
1485  dfref dfr = ThreadGroupGetDFR(0, 1000)
1486  if (DataFolderRefStatus(dfr) == 0)
1487  if (GetRTError(2))
1488  return 0 // no more jobs
1489  endif
1490  else
1491  break
1492  endif
1493  while (1)
1494 
1495  // get input data
1496  wave slabdata = dfr:slabdata
1497  wave image = dfr:image
1498  svar func_param = dfr:func_param
1499  nvar rr = dfr:r_index
1500  nvar ss = dfr:s_index
1501 
1502  // do the work
1503  newdatafolder /s outDF
1504  variable /g r_index = rr
1505  variable /g s_index = ss
1506  wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
1507  variable /g func_result = numpnts(reduced_waves)
1508 
1509  // send output to queue and clean up
1510  adh5_get_result_waves(reduced_waves, "redw_", 0)
1511  WaveClear slabdata, image, reduced_waves
1512  ThreadGroupPutDF 0, :
1513  KillDataFolder dfr
1514  while (1)
1515 
1516  return 0
1517 end
1518 
1519 threadsafe static function /wave reduce_slab_image(slabdata, image, reduction_func, reduction_param)
1520  wave slabdata
1521  wave image
1522  funcref adh5_default_reduction reduction_func
1523  string reduction_param
1524 
1525  switch (WaveDims(slabdata))
1526  case 2:
1527  image = slabdata[q][p]
1528  break
1529  case 3:
1530  image = slabdata[0][q][p]
1531  break
1532  case 4:
1533  image = slabdata[0][0][q][p]
1534  break
1535  endswitch
1536 
1537  return reduction_func(image, reduction_param)
1538 end
1539 
1552 function adh5_loadattr_all(fileID, attributespath)
1553  variable fileID
1554  string attributespath
1555 
1556  string datasetname
1557  string datawavename
1558 
1559  // avoid compilation error if HDF5 XOP has not been loaded
1560  #if Exists("HDF5LoadData")
1561 
1562  // datasets in NDAttributes group
1563  HDF5ListGroup /F /TYPE=2 fileID, attributespath
1564  string h5datasets = S_HDF5ListGroup
1565  HDF5ListAttributes /TYPE=1 /Z fileID, attributespath
1566  string h5attributes = S_HDF5ListAttributes
1567 
1568  variable nds = ItemsInList(h5datasets, ";")
1569  variable na = ItemsInList(h5attributes, ";")
1570  variable ids
1571  variable idest = 0
1572  variable n_attr
1573  string s_attr
1574  string s_source
1575 
1576  make /n=(nds+na) /t /o IN, ID, IV, IU
1577 
1578  for (ids = 0; ids < nds; ids += 1)
1579  datasetname = StringFromList(ids, h5datasets, ";")
1580  HDF5LoadData /O/Q fileID, datasetname
1581  if (v_flag == 0)
1582  datawavename = StringFromList(0, s_wavenames)
1583  else
1584  datawavename = ""
1585  endif
1586  HDF5LoadData /A="source"/O/Q/TYPE=2 fileID, datasetname
1587  if (v_flag == 0)
1588  wave /t source
1589  s_source = source[0]
1590  else
1591  s_source = ""
1592  endif
1593  read_attribute_info(datawavename, s_source, idest)
1594  endfor
1595 
1596  // attributes of NDAttributes group
1597  if (v_flag == 0)
1598  nds = ItemsInList(h5attributes, ";")
1599  else
1600  nds = 0
1601  endif
1602  for (ids = 0; ids < nds; ids += 1)
1603  datasetname = StringFromList(ids, h5attributes, ";")
1604  HDF5LoadData /A=datasetname/O/Q/TYPE=1 fileID, attributespath
1605  if (v_flag == 0)
1606  datawavename = StringFromList(0, s_wavenames)
1607  read_attribute_info(datawavename, "", idest) // we don't get the source of these attributes
1608  endif
1609  endfor
1610 
1611  redimension /n=(idest) IN, ID, IV, IU
1612  sort {IN, ID}, IN, ID, IV, IU
1613 
1614  killwaves /z source
1615  #else
1616  Abort "HDF5 XOP not loaded."
1617  #endif
1618 
1619 end
1620 
1634 static function read_attribute_info(datawavename, source, idest)
1635  string datawavename // name of the attribute wave in the current folder.
1636  // can be text or numeric.
1637  string source
1638  // source identifier (EPICS name) of the attribute.
1639  variable &idest
1640  // destination index in IN, ID, IV, IU where the results are written.
1641  // the variable is incremented if data was written, otherwise it is left unchanged.
1642  // make sure IN, ID, IV, IU have at least idest + 1 elements.
1643 
1644  wave /t IN
1645  wave /t ID
1646  wave /t IV
1647  wave /t IU
1648 
1649  variable n_attr
1650  string s_attr
1651 
1652  if (exists(datawavename) == 1)
1653  if (strlen(source) > 0)
1654  Note $datawavename, "PV=" + source
1655  endif
1656  switch(WaveType($datawavename, 1))
1657  case 1: // numeric
1658  wave w_attr = $datawavename
1659  n_attr = numpnts(w_attr)
1660  sprintf s_attr, "%.12g", w_attr[0]
1661  break
1662  case 2: // text
1663  wave /t wt_attr = $datawavename
1664  n_attr = numpnts(wt_attr)
1665  s_attr = wt_attr[0]
1666  break
1667  default: // unknown
1668  n_attr = 0
1669  endswitch
1670  if (n_attr == 1)
1671  IN[idest] = source
1672  ID[idest] = datawavename
1673  IV[idest] = s_attr
1674  IU[idest] = "" // we don't get the units
1675  idest += 1
1676  endif
1677  endif
1678 end
1679 
1687 function adh5_scale_scienta(data)
1688  wave data
1689 
1690  dfref saveDF = GetDataFolderDFR()
1691 
1692  dfref dataDF = GetWavesDataFolderDFR(data)
1693  dfref attrDF = GetAttrDataFolderDFR(data)
1694 
1695  wave /SDFR=attrDF LensMode
1696  wave /SDFR=attrDF /Z ChannelBegin, ChannelEnd
1697  wave /SDFR=attrDF /Z SliceBegin, SliceEnd
1698 
1699  variable EDim, ADim
1700  variable ELow, EHigh, ALow, AHigh
1701  string EUnit, AUnit
1702 
1703  // which dimension is angle and which one is energy?
1704  strswitch(GetDimLabel(data, 0, -1))
1705  case "AD_Dim0":
1706  EDim = 0
1707  break
1708  case "AD_Dim1":
1709  EDim = 1
1710  break
1711  default:
1712  EDim = -1
1713  endswitch
1714  strswitch(GetDimLabel(data, 1, -1))
1715  case "AD_Dim0":
1716  ADim = 0
1717  break
1718  case "AD_Dim1":
1719  ADim = 1
1720  break
1721  default:
1722  ADim = -1
1723  endswitch
1724 
1725  // defaults (point scaling)
1726  if (EDim >= 0)
1727  ELow = dimoffset(data, EDim)
1728  EHigh = dimoffset(data, EDim) + dimdelta(data, EDim) * (dimsize(data, EDim) - 1)
1729  EUnit = "eV"
1730  endif
1731  if (ADim >= 0)
1732  ALow = dimoffset(data, ADim)
1733  AHigh = dimoffset(data, ADim) + dimdelta(data, ADim) * (dimsize(data, ADim) - 1)
1734  AUnit = "arb."
1735  endif
1736 
1737  // lens mode can give more detail
1738  if (waveexists(LensMode) && (numpnts(LensMode) >= 1))
1739  switch(LensMode[0])
1740  case 1: // Angular45
1741  ALow = -45/2
1742  AHigh = +45/2
1743  AUnit = "°"
1744  break
1745  case 2: // Angular60
1746  ALow = -60/2
1747  AHigh = +60/2
1748  AUnit = "°"
1749  break
1750  endswitch
1751  endif
1752 
1753  // best option if scales are explicit in separate waves
1754  if (waveexists(ChannelBegin) && waveexists(ChannelEnd) && (numpnts(ChannelBegin) >= 1) && (numpnts(ChannelEnd) >= 1))
1755  ELow = ChannelBegin[0]
1756  EHigh = ChannelEnd[0]
1757  endif
1758  if (waveexists(SliceBegin) && waveexists(SliceEnd) && (numpnts(SliceBegin) >= 1) && (numpnts(SliceEnd) >= 1))
1759  ALow = SliceBegin[0]
1760  AHigh = SliceEnd[0]
1761  endif
1762 
1763  // apply new scales
1764  switch(EDim)
1765  case 0:
1766  setscale /i x ELow, EHigh, EUnit, data
1767  break
1768  case 1:
1769  setscale /i y ELow, EHigh, EUnit, data
1770  break
1771  endswitch
1772  switch(ADim)
1773  case 0:
1774  setscale /i x ALow, AHigh, AUnit, data
1775  break
1776  case 1:
1777  setscale /i y ALow, AHigh, AUnit, data
1778  break
1779  endswitch
1780 
1781  setscale d 0, 0, "arb.", data
1782 
1783  setdatafolder saveDF
1784 end
1785 
1792 function adh5_scale_scan(data)
1793  wave data
1794 
1795  dfref saveDF = GetDataFolderDFR()
1796 
1797  dfref dataDF = GetWavesDataFolderDFR(data)
1798  wave /SDFR=dataDF AcquisitionMode, DetectorMode, EnergyMode
1799 
1800  wave /SDFR=dataDF /z Scan1Active, Scan2Active
1801  wave /SDFR=dataDF /t /z Scan1Positioner1, Scan1Readback1
1802  wave /SDFR=dataDF /t /z Scan1Positioner2, Scan1Readback2
1803  wave /SDFR=dataDF /t /z Scan2Positioner1, Scan2Readback1
1804  wave /SDFR=dataDF /t /z Scan2Positioner2, Scan2Readback2
1805 
1806  // TODO : search the data folder for positioner waves,
1807  // i.e. waves with the PV name corresponding to Scan1Positioner1 in their wave note.
1808  wave /z zscale
1809 
1810  strswitch(GetDimLabel(data, 0, -1))
1811  case "AD_DimN":
1812  setscale /i x zscale[0], zscale[numpnts(zscale)-1], "", data
1813  break
1814  endswitch
1815  strswitch(GetDimLabel(data, 1, -1))
1816  case "AD_DimN":
1817  setscale /i y zscale[0], zscale[numpnts(zscale)-1], "", data
1818  break
1819  endswitch
1820  strswitch(GetDimLabel(data, 2, -1))
1821  case "AD_DimN":
1822  setscale /i z zscale[0], zscale[numpnts(zscale)-1], "", data
1823  break
1824  endswitch
1825 
1826  setdatafolder saveDF
1827 end
string adh5_load_preview(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
load a single image from a HDF5 file created by the Area Detector software.
variable kill_progress_panel()
variable display_progress_panel(string title, string message, variable progress_max)
string adh5_load_info(string APathName, string AFileName)
load descriptive info from a HDF5 file created by the Area Detector software.
variable ad_load_dialog(string APathName)
load area detector data files selected in a file dialog window
threadsafe wave ad_profile_x_w(wave dataset, variable q1, variable q2, wave destwave, variable noavg=defaultValue)
1D cut through 2D dataset along X dimension, existing destination wave.
static variable read_attribute_info(string datawavename, string source, variable *idest)
sub-function of adh5_loadattr_all.
static dfr GetAttrDataFolderDFR(wave data)
find the attributes data folder of an area detector dataset.
threadsafe variable adh5_setup_profile(wave image, wave profile, variable dim)
set up a one-dimensional wave for a line profile based on a 2D original wave.
threadsafe variable adh5_get_result_waves(wave results, string result_prefix, variable start_index)
copy waves from wave reference wave into current data folder
variable adh5_scale_scienta(wave data)
set the energy and angle scales of an area detector dataset from the Scienta analyser.
string adh5_test_reduction_func(wave source, funcref reduction_func, string reduction_param, string result_prefix)
wrapper function for testing reduction functions from the command line.
variable adh5_loadattr_all(variable fileID, string attributespath)
load an NDAttributes group from an open HDF5 file into the current data folder.
variable adh5_scale_scan(wave data)
scales the extra dimensions of an area detector dataset according to the EPICS scan ...
string ad_suggest_foldername(string filename, variable ignoredate=defaultValue, string sourcename=defaultValue, variable unique=defaultValue)
generate the name of a data folder based on a file name.
threadsafe wave ad_profile_y_w(wave dataset, variable p1, variable p2, wave destwave, variable noavg=defaultValue)
1D cut through 2D dataset along X dimension, existing destination wave.
string adh5_load_complete(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
import everything from a HDF5 file created by the Area Detector software.
variable adh5_load_reduced_detector(variable fileID, string detectorpath, funcref reduction_func, string reduction_param, variable progress=defaultValue, variable nthreads=defaultValue)
load a reduced detector dataset from the open HDF5 file.
string adh5_load_reduced(string ANickName, string APathName, string AFileName, funcref reduction_func, string reduction_param, variable load_data=defaultValue, variable load_attr=defaultValue, variable progress=defaultValue)
load and reduce a dataset from a HDF5 file created by the Area Detector software. ...
variable adh5_redim(wave data)
redimension a multi-dimensional area detector array loaded from HDF5.
threadsafe wave adh5_default_reduction(wave source, string *param)
function prototype for adh5_load_reduced_detector
variable adh5_load_detector_slabs(variable fileID, string detectorpath, variable progress=defaultValue)
load the detector dataset from the open HDF5 file.
variable adh5_scale(wave data, string source=defaultValue)
set the dimension scales of an area detector dataset.
variable update_progress_panel(variable progress, string message=defaultValue, variable progress_max=defaultValue)
variable adh5_load_detector(variable fileID, string detectorpath)
load the detector dataset from the open HDF5 file.
static threadsafe wave reduce_slab_image(wave slabdata, wave image, funcref reduction_func, string reduction_param)
static variable BeforeFileOpenHook(variable refNum, string fileName, string path, string type, string creator, variable kind)
callback function for drag&drop of HDF5 files into Igor.
string adh5_list_reduction_funcs()
get a list of functions which can be used as reduction functions.
variable adh5_load_detector_image(variable fileID, string detectorpath, variable dim2start, variable dim2count, variable dim3start, variable dim3count)
load a single image from the detector dataset of the open HDF5 file
static threadsafe variable reduce_slab_worker(funcref reduction_func)