PEARL Procedures rev-distro-2.1.1-1-gf419e92-dirty Igor procedures for the analysis of PEARL data

pearl-pshell-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.36
3 #pragma ModuleName = PearlPShellImport
4 #include <HDF5 Browser>
5 #include "pearl-compat"
6 #include "pearl-gui-tools"
7 #include "pearl-area-import"
8
9 // copyright (c) 2013-18 Paul Scherrer Institut
10 //
11 // Licensed under the Apache License, Version 2.0 (the "License");
12 // you may not use this file except in compliance with the License.
13 // You may obtain a copy of the License at
14 // http:///www.apache.org/licenses/LICENSE-2.0
15
58
63
65 strconstant kEnergyDimLabel = "energy"
66
68 strconstant kAngleDimLabel = "angle"
69
71 strconstant kScanDimLabel = "scan"
72
75 strconstant kDataDimLabel = "data"
76
78 strconstant kPreviewDatasets = "ScientaImage;ScientaSpectrum;ImageAngleDistribution;ImageEnergyDistribution;Counts;SampleCurrent;"
79
81 strconstant kScientaScalingDatasets = "LensMode;ScientaChannelBegin;ScientaChannelEnd;ScientaSliceBegin;ScientaSliceEnd;"
82
84 strconstant kTransposedDatasets = "ScientaImage;"
85
87 constant kDetectorSensitivity = 1
88
110 function psh5_open_file(ANickName, APathName, AFileName)
111 string ANickName
112 string APathName
113 string AFileName
114
115 setdatafolder root:
116 newdatafolder /s /o $("root:" + ANickName)
117 dfref fileDF = GetDataFolderDFR()
118
119 variable fileID
120 HDF5OpenFile /P=$APathName /R fileID as AFileName
121 if (v_flag == 0)
122 string /g s_filepath
123 string /g s_scanpaths
124 s_filepath = s_path + s_filename
125 s_scanpaths = psh5_list_scans(fileID)
126 else
127 fileID = 0
128 endif
129
130 return fileID
131 end
132
140 function psh5_close_file(fileID)
141 variable fileID
142
143 HDF5CloseFile fileID
144 end
145
170 function /s psh5_load_complete(ANickName, APathName, AFileName, [load_data, load_attr])
171 string ANickName
172 string APathName
173 string AFileName
174 variable load_data
175 variable load_attr
176
177 if (ParamIsDefault(load_data))
178 load_data = 1
179 endif
180 if (ParamIsDefault(load_attr))
181 load_attr = 1
182 endif
183
184 dfref saveDF = GetDataFolderDFR()
185
186 // performance monitoring
187 variable timerRefNum
188 variable /g psh5_perf_secs
189 timerRefNum = startMSTimer
190
191 variable fileID = psh5_open_file(ANickName, APathName, AFileName)
192 if (fileID)
193 dfref fileDF = GetDataFolderDFR()
194 svar s_filepath
195 svar s_scanpaths
196 AFileName = s_filepath
197 print "loading " + s_filepath + "\r"
198
199 variable ig
200 variable ng = ItemsInList(s_scanpaths, ";")
201 string sg
202 string folder
203
204 for (ig = 0; ig < ng; ig += 1)
205 sg = StringFromList(ig, s_scanpaths, ";")
206 folder = ReplaceString("/", sg, "")
207 folder = ReplaceString(" ", folder, "")
208 folder = PearlCleanupName(folder)
209 setdatafolder fileDF
210 newdatafolder /s /o $folder
211 psh5_load_scan_complete(fileID, sg, load_data=load_data, load_attr=load_attr)
212 endfor
213
214 psh5_close_file(fileID)
215 else
216 AFileName = ""
217 endif
218
219 psh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
220
221 setdatafolder saveDF
222 return AFileName
223 end
224
251 function /s psh5_load_preview(APathName, AFileName, [load_data, load_attr, pref_scans, pref_datasets])
252 string APathName
253 string AFileName
254 variable load_data
255 variable load_attr
256 string pref_scans
257 string pref_datasets
258
259 if (ParamIsDefault(load_data))
260 load_data = 1
261 endif
262 if (ParamIsDefault(load_attr))
263 load_attr = 1
264 endif
265 if (ParamIsDefault(pref_scans))
266 pref_scans = "*scan1*;"
267 endif
268 if (ParamIsDefault(pref_datasets))
269 pref_datasets = ""
270 endif
271
272 dfref saveDF = GetDataFolderDFR()
273
274 variable fileID
275 string scanpaths = ""
276 string dataname = ""
277
278 // performance monitoring
279 variable timerRefNum
280 variable /g adh5_perf_secs
281 timerRefNum = startMSTimer
282
283 HDF5OpenFile /P=$APathName /R /Z fileID as AFileName
284 if (v_flag == 0)
285 AFileName = s_path + s_filename
286 dfref fileDF = GetDataFolderDFR()
287
288 scanpaths = psh5_list_scans(fileID)
289 variable ng = ItemsInList(scanpaths)
290 variable ig
291 string sg
292 variable np = ItemsInList(pref_scans)
293 variable ip
294 string sp
295 variable found = 0
296 if (ng > 0)
297 for (ip = 0; ip < np; ip += 1)
298 for (ig = 0; ig < ng; ig += 1)
299 sg = StringFromList(ig, scanpaths)
300 sp = StringFromList(ip, pref_scans)
301 if (StringMatch(sg, sp))
302 found = 1
303 break
304 endif
305 endfor
306 if (found)
307 break
308 endif
309 endfor
310 if (!found)
311 ig = 0
312 endif
313 sg = StringFromList(ig, scanpaths)
314
315 if (load_attr)
316 setdatafolder fileDF
317 newdatafolder /o/s attr
318 killwaves /a/z
319 psh5_load_scan_attrs(fileID, sg)
320 endif
321
322 setdatafolder fileDF
323 dataname = psh5_load_scan_preview(fileID, sg, set_scale=load_attr, pref_datasets=pref_datasets)
324 else
325 print "no scans found in file " + AFileName
326 endif
327
328 HDF5CloseFile fileID
329 endif
330
331 if (timerRefNum >= 0)
332 adh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
333 endif
334
335 setdatafolder saveDF
336 return dataname
337 end
338
361 function /s psh5_load_scan_complete(fileID, scanpath, [load_data, load_attr])
362 variable fileID
363 string scanpath
364 variable load_data
365 variable load_attr
366
367 if (ParamIsDefault(load_data))
368 load_data = 1
369 endif
370 if (ParamIsDefault(load_attr))
371 load_attr = 1
372 endif
373
374 dfref saveDF = GetDataFolderDFR()
375
376 dfref dataDF = GetDataFolderDFR()
377 string wavenames
378 string attrnames
379 psh5_load_scan_meta(fileID, scanpath)
380 if (load_attr)
381 newdatafolder /s /o attr
382 attrnames = psh5_load_scan_attrs(fileID, scanpath)
383 endif
384 if (load_data)
385 setdatafolder dataDF
386 wavenames = psh5_load_scan_data(fileID, scanpath)
387 endif
388 if (load_data && load_attr)
389 setdatafolder dataDF
390 ps_scale_datasets()
391 endif
392
393 setdatafolder saveDF
394 return wavenames
395 end
396
405 function /s psh5_list_scans(fileID)
406 variable fileID
407
408 HDF5ListGroup /F /TYPE=1 fileID, "/"
409
410 variable ig
411 variable ng = ItemsInList(S_HDF5ListGroup, ";")
412 string sg
413 string scans = ""
414
415 for (ig = 0; ig < ng; ig += 1)
416 sg = StringFromList(ig, S_HDF5ListGroup, ";")
417 if (cmpstr(sg[1,4], "scan") == 0)
418 scans = AddListItem(sg, scans, ";", inf)
419 endif
420 endfor
421
422 return scans
423 end
424
440 function /s psh5_list_scan_datasets(fileID, scanpath, [include_regions])
441 variable fileID
442 string scanpath
443 variable include_regions
444
445 if (ParamIsDefault(include_regions))
446 include_regions = 0
447 endif
448 string result
449
450 HDF5ListGroup /TYPE=2 /Z fileID, scanpath
451 result = S_HDF5ListGroup
452
453 if (include_regions)
454 HDF5ListGroup /R /TYPE=2 /Z fileID, scanpath
455 variable n = ItemsInList(S_HDF5ListGroup)
456 variable i
457 string ds
458 string region_datasets
459 for (i = 0; i < n; i += 1)
460 ds = StringFromList(i, S_HDF5ListGroup)
461 if (StringMatch(ds, "region*/*"))
462 //region_datasets = psh5_list_scan_datasets(fileID, ReplaceString("//", scanpath + "/" + region, "/"), include_regions=0)
463 result = AddListItem(ds, result, ";", inf)
464 endif
465 endfor
466 endif
467
468 return result
469 end
470
481 function /s psh5_list_scan_regions(fileID, scanpath)
482 variable fileID
483 string scanpath
484
485 HDF5ListGroup /TYPE=1 /Z fileID, scanpath
486 variable n = ItemsInList(S_HDF5ListGroup)
487 variable i
488 string result = ""
489 string s
490 for (i = 0; i < n; i += 1)
491 s = StringFromList(i, S_HDF5ListGroup)
492 if (StringMatch(s, "region*"))
493 result = AddListItem(s, result, ";", inf)
494 endif
495 endfor
496
497 return result
498 end
499
514 function /s psh5_load_scan_data(fileID, scanpath)
515 variable fileID
516 string scanpath
517
518 string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
519 variable nds = ItemsInList(datasets)
520 variable ids
521 string sds
522 string sw
523 string wavenames = ""
524 for (ids = 0; ids < nds; ids += 1)
525 sds = StringFromList(ids, datasets)
526 sw = psh5_load_dataset(fileID, scanpath, sds, set_scale=0)
527 wavenames = AddListItem(sw, wavenames, ";", inf)
528 endfor
529
530 return wavenames
531 end
532
554 function /s psh5_load_scan_attrs(fileID, scanpath, [attr_sets])
555 variable fileID
556 string scanpath
557 variable attr_sets
558
559 if (ParamIsDefault(attr_sets))
560 attr_sets = 1
561 endif
562
563 string attr_path = ReplaceString("//", scanpath + "/attrs", "/")
564 string attr_list = ""
565 if (attr_sets & 1)
566 HDF5ListGroup /TYPE=2 /Z fileID, attr_path
567 if (!v_flag)
568 attr_list = S_HDF5ListGroup
569 endif
570 endif
571
572 variable ids
573 variable nds
574 string sds
575
576 if (attr_sets & 2)
577 nds = ItemsInList(kScientaScalingDatasets, ";")
578 for (ids = 0; ids < nds; ids += 1)
579 sds = StringFromList(ids, kScientaScalingDatasets)
580 if (WhichListItem(sds, attr_list) < 0)
581 attr_list = AddListItem(sds, attr_list, ";", inf)
582 endif
583 endfor
584 endif
585
586 nds = ItemsInList(attr_list, ";")
587 string wavenames = ""
588 for (ids = 0; ids < nds; ids += 1)
589 sds = StringFromList(ids, attr_list, ";")
590 HDF5LoadData /O /Q /Z fileID, attr_path + "/" + sds
591 if (!v_flag)
592 wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
593 endif
594 endfor
595 wavenames = ReplaceString(";;", wavenames, ";")
596
597 return wavenames
598 end
599
625 function /s psh5_load_scan_meta(fileID, scanpath)
626 variable fileID
627 string scanpath
628 string wavenames = ""
629
630 HDF5LoadData /O /Q /Z /A="Dimensions" /N=ScanDimensions /TYPE=1 fileID, scanpath
631 if (!v_flag)
632 wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
633 else
634 make /n=1 /o ScanDimensions
635 ScanDimensions = 0
636 wavenames = AddListItem("ScanDimensions", wavenames, ";", inf)
637 endif
638 HDF5LoadData /O /Q /Z /A="Readables" /N=ScanReadables /TYPE=1 fileID, scanpath
639 if (!v_flag)
640 wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
641 else
642 make /n=1 /o /t ScanReadables
643 ScanReadables[0] = "ScientaSpectrum"
644 wavenames = AddListItem("ScanReadables", wavenames, ";", inf)
645 endif
646 HDF5LoadData /O /Q /Z /A="Writables" /N=ScanWritables /TYPE=1 fileID, scanpath
647 if (!v_flag)
648 wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
649 endif
650 HDF5LoadData /O /Q /Z /A="Steps" /N=ScanSteps /TYPE=1 fileID, scanpath
651 if (!v_flag)
652 wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
653 endif
654 wavenames = ReplaceString(";;", wavenames, ";")
655
656 // additional attributes from XPSSpectrum.py
657 HDF5LoadData /O /Q /Z /A="Iterations" /N=ScanIterations /TYPE=1 fileID, scanpath
658 if (!v_flag)
659 wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
660 endif
661 HDF5LoadData /O /Q /Z /A="Step Size" /N=ScanStepSize /TYPE=1 fileID, scanpath
662 if (!v_flag)
663 wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
664 endif
665 HDF5LoadData /O /Q /Z /A="Step Time" /N=ScanStepTime /TYPE=1 fileID, scanpath
666 if (!v_flag)
667 wavenames = AddListItem(s_wavenames, wavenames, ";", inf)
668 endif
669
670 return wavenames
671 end
672
706 function /s psh5_load_dataset(fileID, scanpath, datasetname, [set_scale])
707 variable fileID
708 string scanpath
709 string datasetname
710 variable set_scale
711
712 if (ParamIsDefault(set_scale))
713 set_scale = 1
714 endif
715
716 dfref base_df = GetDataFolderDFR()
717
718 string datasetpath
719 datasetpath = scanpath + "/" + datasetname
720 datasetpath = ReplaceString("//", datasetpath, "/")
721
722 string regionname
723 string regionpath
724 if (ItemsInList(datasetname, "/") >= 2)
725 regionname = StringFromList(0, datasetname, "/")
726 regionpath = ReplaceString("//", scanpath + "/" + regionname, "/")
727 datasetname = RemoveListItem(0, datasetname, "/")
728 NewDataFolder /o/s $regionname
729 else
730 regionname = ""
731 regionpath = scanpath
732 endif
733
734 STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
735 InitHDF5DataInfo(di)
736 variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
737 if (err != 0)
738 print "error accessing detector/data"
739 return ""
740 endif
741
742 string dataname
743 if (di.ndims < 2)
744 HDF5LoadData /O /Q /Z fileID, datasetpath
745 dataname = StringFromList(0, S_waveNames)
746 else
747 dataname = psh5_load_dataset_slabs(fileID, regionpath, datasetname)
748 endif
749
750 wave /z data = $dataname
751 if (waveexists(data))
752 psh5_load_dataset_meta(fileID, regionpath, datasetname, data)
753 ps_set_dimlabels(data)
754 if (set_scale)
755 ps_scale_dataset(data)
756 endif
757 else
758 dataname = ""
759 endif
760
761 setdatafolder base_df
762 return dataname
763 end
764
778 static function /s select_dataset(file_datasets, pref_datasets)
779 string file_datasets
780 string pref_datasets
781
782 variable index
783 variable nds = ItemsInList(file_datasets)
784 variable ids
785 string sds = ""
786 string mds = ""
787 variable np = ItemsInList(pref_datasets)
788 variable ip
789 string sp
790 variable found = 0
791 if (nds > 0)
792 for (ip = 0; ip < np; ip += 1)
793 for (ids = 0; ids < nds; ids += 1)
794 sds = StringFromList(ids, file_datasets)
795 index = ItemsInList(sds, "/") - 1
796 mds = StringFromList(index, sds, "/")
797 sp = StringFromList(ip, pref_datasets)
798 if (StringMatch(mds, sp))
799 found = 1
800 break
801 endif
802 endfor
803 if (found)
804 break
805 endif
806 endfor
807 if (!found)
808 ids = 0
809 sds = StringFromList(ids, file_datasets)
810 endif
811 endif
812
813 return sds
814 end
815
840 function /s psh5_load_scan_preview(fileID, scanpath, [set_scale, pref_datasets])
841 variable fileID
842 string scanpath
843 variable set_scale
844 string pref_datasets
845
846 if (ParamIsDefault(set_scale))
847 set_scale = 1
848 endif
849 if (ParamIsDefault(pref_datasets) || (strlen(pref_datasets) == 0))
850 pref_datasets = kPreviewDatasets
851 endif
852
853 dfref saveDF = GetDataFolderDFR()
854 dfref dataDF = saveDF
855
856 string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
857 string datasetname = select_dataset(datasets, pref_datasets)
858 string datasetpath
859 datasetpath = scanpath + "/" + datasetname
860 datasetpath = ReplaceString("//", datasetpath, "/")
861
862 STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
863 InitHDF5DataInfo(di)
864 variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
865 if (err != 0)
866 print "error accessing detector/data"
867 return ""
868 endif
869
870 string dataname
871 if (di.ndims < 2)
872 HDF5LoadData /O /Q /Z fileID, datasetpath
873 dataname = StringFromList(0, S_waveNames)
874 wave /z data = $dataname
875 if (waveexists(data))
876 ps_set_dimlabels(data)
877 endif
878 else
879 variable dim2start = 0
880 variable dim2count = 1
881 variable dim3start = 0
882 variable dim3count = 1
883 if (di.ndims >= 3)
884 dim2start = floor(di.dims[2] / 2)
885 dim2count = 1
886 endif
887 if (di.ndims >= 4)
888 dim3start = floor(di.dims[3] / 2)
889 dim3count = 1
890 endif
891
892 dataname = psh5_load_dataset_slab(fileID, scanpath, datasetname, dim2start, dim2count, dim3start, dim3count)
893 endif
894
895 wave /z data = $dataname
896 if (waveexists(data))
897 if (set_scale)
898 setdatafolder dataDF
899 string positioners
900 string positioner
901 string positionerpath
902 positioners = psh5_load_scan_meta(fileID, scanpath)
903 wave /t /z ScanWritables
904 if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
905 positioner = ScanWritables[0]
906 if (strlen(positioner) > 0)
907 positionerpath = scanpath + "/" + positioner
908 positionerpath = ReplaceString("//", positionerpath, "/")
909 HDF5LoadData /O /Q /Z fileID, positionerpath
910 endif
911 endif
912
913 setdatafolder dataDF
914 newdatafolder /o/s attr
915 psh5_load_scan_attrs(fileID, scanpath, attr_sets=2)
916 setdatafolder dataDF
917 ps_scale_dataset(data)
918 endif
919 else
920 dataname = ""
921 endif
922
923 return dataname
924 end
925
953 function /s psh5_load_scan_section(fileID, scanpath, dim, [set_scale, pref_datasets])
954 variable fileID
955 string scanpath
956 variable dim
957 variable set_scale
958 string pref_datasets
959
960 // select first dimension (future argument)
961 // 0 = first dimension is x axis (energy of scienta image)
962 dim = 0
963
964 if (ParamIsDefault(set_scale))
965 set_scale = 1
966 endif
967 if (ParamIsDefault(pref_datasets) || (strlen(pref_datasets) == 0))
968 pref_datasets = kPreviewDatasets
969 endif
970
971 dfref saveDF = GetDataFolderDFR()
972 dfref dataDF = saveDF
973
974 string datasets = psh5_list_scan_datasets(fileID, scanpath)
975 string datasetname = select_dataset(datasets, pref_datasets)
976 string datasetpath
977 datasetpath = scanpath + "/" + datasetname
978 datasetpath = ReplaceString("//", datasetpath, "/")
979 string dataname = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
980 string destname = dataname[0,29] + num2str(dim)
981
982 STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
983 InitHDF5DataInfo(di)
984 variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
985 if (err != 0)
986 print "error accessing detector/data"
987 return ""
988 elseif (di.ndims != 3)
989 print "error: rank of dataset != 3"
990 return ""
991 endif
992
993 variable idx, idy, idz, idt
994 variable transpose = WhichListItem(dataname, kTransposedDatasets) >= 0
995 if (transpose)
996 idx = 1
997 idy = 0
998 else
999 idx = 0
1000 idy = 1
1001 endif
1002 idz = 2
1003 idt = 3
1004
1005 variable nx, ny, nz
1006 nx = di.dims[idx]
1007 ny = di.dims[idy]
1008 nz = di.dims[idz]
1009
1010 HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
1011 wave slab
1012 slab[][%Start] = 0
1013 slab[][%Stride] = 1
1014 slab[][%Count] = 1
1015 slab[][%Block] = 1
1016
1017 if (dim == 0)
1018 slab[idy][%Start] = floor(ny / 2)
1019 slab[idx][%Block] = nx
1020 make /n=(nx,nz) /o $destname
1021 else
1022 slab[idx][%Start] = floor(nx / 2)
1023 slab[idy][%Block] = ny
1024 make /n=(ny,nz) /o $destname
1025 endif
1026 slab[idz][%Block] = nz
1027 wave data = $destname
1028 data = 0
1029
1030 HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
1031 if (!v_flag)
1032 wave slabdata
1033 if (transpose)
1034 data += slabdata[0][p][q][0]
1035 else
1036 data += slabdata[p][0][q][0]
1037 endif
1038 endif
1039 killwaves /z slab, slabdata
1040
1041 if (set_scale)
1042 make /n=(1,1,1) /free dummy
1043 ps_set_dimlabels2(dummy, dataname)
1044 setdimlabel 0, -1, $GetDimLabel(dummy, dim, -1), data
1045 setdimlabel 1, -1, $kScanDimLabel, data
1046
1047 setdatafolder dataDF
1048 string positioners
1049 string positioner
1050 string positionerpath
1051 positioners = psh5_load_scan_meta(fileID, scanpath)
1052 wave /t /z ScanWritables
1053 if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
1054 positioner = ScanWritables[0]
1055 if (strlen(positioner) > 0)
1056 positionerpath = scanpath + "/" + positioner
1057 positionerpath = ReplaceString("//", positionerpath, "/")
1058 HDF5LoadData /O /Q /Z fileID, positionerpath
1059 endif
1060 endif
1061
1062 setdatafolder dataDF
1063 newdatafolder /o/s attr
1064 killwaves /a/z
1065 psh5_load_scan_attrs(fileID, scanpath, attr_sets=2)
1066 setdatafolder dataDF
1067 ps_scale_dataset(data)
1068 endif
1069
1070 return destname
1071 end
1072
1091 function psh5_load_dataset_meta(fileID, datapath, datasetname, datawave)
1092 variable fileID
1093 string datapath
1094 string datasetname
1095 wave datawave
1096
1097 dfref saveDF = GetDataFolderDFR()
1098 SetDataFolder NewFreeDataFolder()
1099
1100 string datasetpath = datapath + "/" + datasetname
1101 datasetpath = ReplaceString("//", datasetpath, "/")
1102 string wnote
1103
1104 HDF5LoadData /O /Q /Z /A="Writable Dimension" /N=WriteDim fileID, datasetpath
1105 if (!v_flag)
1106 wave WriteDim
1107 // scan dimension starts at 1
1108 sprintf wnote, "ScanDimension=%u", WriteDim[0]
1109 Note datawave, wnote
1110 endif
1111
1112 HDF5LoadData /O /Q /Z /A="Writable Index" /N=WriteIndex fileID, datasetpath
1113 if (!v_flag)
1114 wave WriteIndex
1115 sprintf wnote, "WriteableIndex=%u", WriteIndex[0]
1116 Note datawave, wnote
1117 endif
1118
1119 HDF5LoadData /O /Q /Z /A="Readable Index" /N=ReadIndex fileID, datasetpath
1120 if (!v_flag)
1121 wave ReadIndex
1122 sprintf wnote, "ReadableIndex=%u", ReadIndex[0]
1123 Note datawave, wnote
1124 endif
1125
1126 setdatafolder saveDF
1127 return 0
1128 end
1129
1148 function /s psh5_load_dataset_slabs(fileID, datapath, datasetname, [progress])
1149 variable fileID
1150 string datapath
1151 string datasetname
1152 variable progress
1153
1154 if (ParamIsDefault(progress))
1155 progress = 1
1156 endif
1157
1158 variable result = 0
1159 string datasetpath
1160 string datawavename
1161 datasetpath = datapath + "/" + datasetname
1162 datasetpath = ReplaceString("//", datasetpath, "/")
1163 datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
1164
1165 STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
1166 InitHDF5DataInfo(di)
1167 variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
1168 if (err != 0)
1169 print "error accessing detector/data"
1170 return ""
1171 endif
1172 if (di.ndims < 2)
1173 print "error: rank of dataset < 2"
1174 return ""
1175 elseif (di.ndims < 3)
1176 progress = 0
1177 endif
1178
1179 variable idx, idy, idz, idt, izt
1180 variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
1181 if (transpose)
1182 idx = 1
1183 idy = 0
1184 else
1185 idx = 0
1186 idy = 1
1187 endif
1188 idz = 2
1189 idt = 3
1190
1191 variable nx, ny, nz, nt, nzt
1192 nx = di.dims[idx]
1193 ny = di.dims[idy]
1194 nz = di.dims[idz]
1195 nt = di.dims[idt]
1196 make /n=(nx,ny,nz,nt) /o $datawavename
1197 wave data = $datawavename
1198
1199 nz = max(nz, 1)
1200 nt = max(nt, 1)
1201 nzt = nz * nt
1202 izt = 0
1203 if (progress)
1204 display_progress_panel("HDF5 Import", "Loading data...", nzt)
1205 endif
1206
1207 // load data image by image
1208 HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
1209 wave slab
1210 slab[][%Start] = 0
1211 slab[][%Stride] = 1
1212 slab[][%Count] = 1
1213 slab[][%Block] = 1
1214 slab[idx][%Block] = nx
1215 slab[idy][%Block] = ny
1216
1217 variable iz, it
1218 for (iz = 0; iz < nz; iz += 1)
1219 for (it = 0; it < nt; it += 1)
1220 slab[idz][%Start] = iz
1221 slab[idt][%Start] = it
1222 HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
1223 wave slabdata // 2D, 3D, or 4D with singletons
1224 if (transpose)
1225 data[][][iz][it] = slabdata[q][p][0][0]
1226 else
1227 data[][][iz][it] = slabdata[p][q][0][0]
1228 endif
1229
1230 // progress window
1231 izt += 1
1232 if (progress)
1233 if (update_progress_panel(izt))
1234 result = -4 // user abort
1235 break
1236 endif
1237 endif
1238 endfor
1239 if (result < 0)
1240 break
1241 endif
1242 endfor
1243
1244 if (progress)
1245 kill_progress_panel()
1246 endif
1247
1248 killwaves /z slab, slabdata
1249 if (!result)
1250 ps_set_dimlabels(data)
1251 return datawavename
1252 else
1253 killwaves /z data
1254 return ""
1255 endif
1256 end
1257
1284 function /s psh5_load_dataset_slab(fileID, datapath, datasetname, dim2start, dim2count, dim3start, dim3count)
1285 variable fileID
1286 string datapath
1287 string datasetname
1288 variable dim2start
1289 variable dim2count
1290 variable dim3start
1291 variable dim3count
1292
1293 string datasetpath
1294 string datawavename
1295 datasetpath = datapath + "/" + datasetname
1296 datasetpath = ReplaceString("//", datasetpath, "/")
1297 datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
1298
1299 STRUCT HDF5DataInfo di
1300 InitHDF5DataInfo(di)
1301 variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
1302 if (err != 0)
1303 print "error accessing detector/data"
1304 return ""
1305 endif
1306 if (di.ndims < 2)
1307 print "error: rank of dataset < 2"
1308 return ""
1309 endif
1310
1311 variable idx, idy, idz, idt
1312 variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
1313 if (transpose)
1314 idx = 1
1315 idy = 0
1316 else
1317 idx = 0
1318 idy = 1
1319 endif
1320 idz = 2
1321 idt = 3
1322
1323 variable nx, ny
1324 nx = di.dims[idx]
1325 ny = di.dims[idy]
1326 make /n=(nx,ny) /o $datawavename
1327 wave data = $datawavename
1328 data = 0
1329
1330 HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
1331 wave slab
1332 slab[][%Start] = 0
1333 slab[][%Stride] = 1
1334 slab[][%Count] = 1
1335 slab[][%Block] = 1
1336 slab[idx][%Block] = nx
1337 slab[idy][%Block] = ny
1338
1339 variable iz, it
1340 variable navg = 0
1341 variable dim2end = dim2start + dim2count - 1
1342 variable dim3end = dim3start + dim3count - 1
1343 for (iz = dim2start; iz <= dim2end; iz += 1)
1344 for (it = dim3start; it <= dim3end; it += 1)
1345 slab[idz][%Start] = iz
1346 slab[idt][%Start] = it
1347 HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
1348 if (!v_flag)
1349 wave slabdata
1350 if (transpose)
1351 data += slabdata[q][p][0][0]
1352 else
1353 data += slabdata[p][q][0][0]
1354 endif
1355 navg += 1
1356 endif
1357 endfor
1358 endfor
1359 if (navg)
1360 data /= navg
1361 endif
1362
1363 killwaves /z slab, slabdata
1364 ps_set_dimlabels(data)
1365 return datawavename
1366 end
1367
1383 function ps_set_dimlabels(data)
1384 wave data
1385
1386 ps_set_dimlabels2(data, NameOfWave(data))
1387 end
1388
1402 function ps_set_dimlabels2(data, name)
1403 wave data
1404 string name
1405
1406 variable dummy
1407 try
1408 // intrinsic dimensions
1409 strswitch(name)
1410 case "ScientaImage":
1411 setdimlabel 0, -1, $kEnergyDimLabel, data
1412 setdimlabel 1, -1, $kAngleDimLabel, data
1413 if (WaveDims(data) >= 3)
1414 setdimlabel 2, -1, $kScanDimLabel, data
1415 endif
1416 AbortOnRTE
1417 break
1418 case "ImageAngleDistribution":
1419 case "ScientaAngleDistribution":
1420 if (WaveDims(data) >= 2)
1421 setdimlabel 0, -1, $kScanDimLabel, data
1422 setdimlabel 1, -1, $kAngleDimLabel, data
1423 else
1424 setdimlabel 0, -1, $kAngleDimLabel, data
1425 endif
1426 AbortOnRTE
1427 break
1428 case "ScientaSpectrum":
1429 case "ImageEnergyDistribution":
1430 case "ScientaEnergyDistribution":
1431 if (WaveDims(data) >= 2)
1432 setdimlabel 0, -1, $kScanDimLabel, data
1433 setdimlabel 1, -1, $kEnergyDimLabel, data
1434 else
1435 setdimlabel 0, -1, $kEnergyDimLabel, data
1436 endif
1437 AbortOnRTE
1438 break
1439 default:
1440 if (WaveDims(data) == 1)
1441 setdimlabel 0, -1, $kScanDimLabel, data
1442 AbortOnRTE
1443 else
1444 return 1
1445 endif
1446 endswitch
1447 catch
1448 dummy = GetRTError(1)
1449 return 2
1450 endtry
1451 return 0
1452 end
1453
1459 static function /df find_scan_folder(dataDF)
1460 dfref dataDF
1461
1462 dfref attrDF = dataDF:attr
1463 if (!DataFolderRefStatus(attrDF))
1464 string df = GetDataFolder(1, dataDF) + ":"
1465 dfref scanDF = $df
1466 else
1467 dfref scanDF = dataDF
1468 endif
1469 return scanDF
1470 end
1471
1476 static function /df find_attr_folder(dataDF)
1477 dfref dataDF
1478
1479 dfref attrDF = dataDF:attr
1480 if (!DataFolderRefStatus(attrDF))
1481 string df = GetDataFolder(1, dataDF) + ":"
1482 dfref scanDF = $df
1483 dfref attrDF = scanDF:attr
1484 endif
1485 return attrDF
1486 end
1487
1504 function ps_scale_datasets()
1505 dfref scanDF = GetDataFolderDFR()
1506 dfref attrDF = find_attr_folder(scanDF)
1507
1508 make /n=3 /free lo, hi
1509 make /n=3 /t /free ax, un
1510 wave /t /z /SDFR=scanDF ScanReadables
1511 if (WaveExists(ScanReadables))
1512 variable isr
1513 variable nsr = numpnts(ScanReadables)
1514 string ssr
1515 string sdf
1516 for (isr = 0; isr < nsr; isr += 1)
1517 setdatafolder scanDF
1518 ssr = ScanReadables[isr]
1519 if (ItemsInList(ssr, "/") >= 2)
1520 sdf = StringFromList(0, ssr, "/")
1521 ssr = RemoveListItem(0, ssr, "/")
1522 setdatafolder $sdf
1523 endif
1524 wave /z wsr=$ssr
1525 if (WaveExists(wsr))
1526 ps_detect_scale(ax, lo, hi, un)
1527 ps_scale_dataset_2(wsr, ax, lo, hi, un)
1528 endif
1529 endfor
1530 endif
1531 setdatafolder scanDF
1532 end
1533
1550 function ps_scale_dataset(data)
1551 wave data
1552
1553 dfref saveDF = GetDataFolderDFR()
1554 dfref dataDF = GetWavesDataFolderDFR(data)
1555
1556 setdatafolder dataDF
1557 make /n=3 /free lo, hi
1558 make /n=3 /t /free ax, un
1559 ps_detect_scale(ax, lo, hi, un)
1560 ps_scale_dataset_2(data, ax, lo, hi, un)
1561 setdatafolder saveDF
1562 end
1563
1564 static function /wave find_scale_wave(name, dataDF, scanDF, attrDF)
1565 string name
1566 dfref dataDF
1567 dfref scanDF
1568 dfref attrDF
1569
1570 wave /SDFR=dataDF /Z w = $name
1571 if (!WaveExists(w))
1572 wave /SDFR=scanDF /Z w = $name
1573 if (!WaveExists(w))
1574 wave /SDFR=attrDF /Z w = $name
1575 endif
1576 endif
1577 return w
1578 end
1579
1621 function ps_detect_scale(ax, lo, hi, un)
1622 wave /t ax
1623 wave lo
1624 wave hi
1625 wave /t un
1626
1627 dfref dataDF = GetDataFolderDFR()
1628 dfref scanDF = find_scan_folder(dataDF)
1629 dfref attrDF = find_attr_folder(dataDF)
1630
1631 redimension /n=4 lo, hi, un, ax
1632 setdimlabel 0, 0, $kEnergyDimLabel, lo, hi, un, ax
1633 setdimlabel 0, 1, $kAngleDimLabel, lo, hi, un, ax
1634 setdimlabel 0, 2, $kScanDimLabel, lo, hi, un, ax
1635 setdimlabel 0, 3, $kDataDimLabel, lo, hi, un, ax
1636
1637 // default values
1638 lo[%$kEnergyDimLabel] = 0
1639 hi[%$kEnergyDimLabel] = 1
1640 un[%$kEnergyDimLabel] = "eV"
1641 ax[%$kEnergyDimLabel] = "Ekin"
1642
1643 lo[%$kAngleDimLabel] = -1
1644 hi[%$kAngleDimLabel] = 1
1645 un[%$kAngleDimLabel] = "arb."
1646 un[%$kAngleDimLabel] = "slice"
1647
1648 lo[%$kScanDimLabel] = 0
1649 hi[%$kScanDimLabel] = 1
1650 un[%$kScanDimLabel] = "arb."
1651 ax[%$kScanDimLabel] = "scan"
1652
1653 lo[%$kDataDimLabel] = 0
1654 hi[%$kDataDimLabel] = 0
1655 un[%$kDataDimLabel] = "arb."
1656 ax[%$kDataDimLabel] = "value"
1657
1658 wave /SDFR=attrDF /T /Z LensMode
1659 wave /Z ChannelBegin = find_scale_wave("ScientaChannelBegin", dataDF, scanDF, attrDF)
1660 wave /Z ChannelEnd = find_scale_wave("ScientaChannelEnd", dataDF, scanDF, attrDF)
1661 wave /Z SliceBegin = find_scale_wave("ScientaSliceBegin", dataDF, scanDF, attrDF)
1662 wave /Z SliceEnd = find_scale_wave("ScientaSliceEnd", dataDF, scanDF, attrDF)
1663
1664 // lens mode can give more detail
1665 if (waveexists(LensMode) && (numpnts(LensMode) >= 1))
1666 strswitch(LensMode[0])
1667 case "Angular45":
1668 lo[%$kAngleDimLabel] = -45/2
1669 hi[%$kAngleDimLabel] = +45/2
1670 un[%$kAngleDimLabel] = "°"
1671 ax[%$kAngleDimLabel] = "angle"
1672 break
1673 case "Angular60":
1674 lo[%$kAngleDimLabel] = -60/2
1675 hi[%$kAngleDimLabel] = +60/2
1676 un[%$kAngleDimLabel] = "°"
1677 ax[%$kAngleDimLabel] = "angle"
1678 break
1679 case "Transmission":
1680 un[%$kAngleDimLabel] = "arb."
1681 ax[%$kAngleDimLabel] = "offset"
1682 break
1683 endswitch
1684 endif
1685
1686 // best option if scales are explicit in separate waves
1687 if (waveexists(ChannelBegin) && waveexists(ChannelEnd) && (numpnts(ChannelBegin) >= 1) && (numpnts(ChannelEnd) >= 1))
1688 lo[%$kEnergyDimLabel] = ChannelBegin[0]
1689 hi[%$kEnergyDimLabel] = ChannelEnd[0]
1690 endif
1691 if (waveexists(SliceBegin) && waveexists(SliceEnd) && (numpnts(SliceBegin) >= 1) && (numpnts(SliceEnd) >= 1))
1692 lo[%$kAngleDimLabel] = SliceBegin[0]
1693 hi[%$kAngleDimLabel] = SliceEnd[0]
1694 endif
1695
1696 wave /z /t /SDFR=scanDF ScanWritables
1697 if (WaveExists(ScanWritables))
1698 wave /z /SDFR=scanDF scanner = $ScanWritables[0]
1699 if (!WaveExists(scanner))
1700 wave /z /SDFR=attrDF scanner = $ScanWritables[0]
1701 endif
1702 if (WaveExists(scanner) && (numpnts(scanner) >= 1))
1703 lo[%$kScanDimLabel] = scanner[0]
1704 hi[%$kScanDimLabel] = scanner[numpnts(scanner)-1]
1705 ax[%$kScanDimLabel] = NameOfWave(scanner)
1706 strswitch(NameOfWave(scanner))
1707 case "Eph":
1708 ax[%$kScanDimLabel] = "photon energy"
1709 un[%$kScanDimLabel] = "eV"
1710 break
1711 case "ManipulatorX":
1712 case "ManipulatorY":
1713 case "ManipulatorZ":
1714 case "FocusYTrans":
1715 case "FocusZTrans":
1716 case "RefocusYTrans":
1717 case "RefocusZTrans":
1718 case "ExitSlitY":
1719 un[%$kScanDimLabel] = "mm"
1720 break
1721 case "ExitSlit":
1722 un[%$kScanDimLabel] = "µm"
1723 break
1724 case "ManipulatorTheta":
1725 case "ManipulatorTilt":
1726 case "ManipulatorPhi":
1727 un[%$kScanDimLabel] = "°"
1728 break
1729 case "FocusXRot":
1730 case "FocusYRot":
1731 case "FocusZRot":
1732 case "RefocusXRot":
1733 case "RefocusYRot":
1734 case "RefocusZRot":
1735 un[%$kScanDimLabel] = "mrad"
1736 break
1737 endswitch
1738 endif
1739 endif
1740 end
1741
1781 function ps_scale_dataset_2(data, ax, lo, hi, un)
1782 wave data
1783 wave /t ax
1784 wave lo
1785 wave hi
1786 wave /t un
1787
1788 string snote = note(data)
1789 string sdim
1790 sdim = GetDimLabel(data, 0, -1)
1791 if (strlen(sdim))
1792 setscale /i x lo[%$sdim], hi[%$sdim], un[%$sdim], data
1793 snote = ReplaceStringByKey("AxisLabelX", snote, ax[%$sdim], "=", "\r")
1794 endif
1795
1796 sdim = GetDimLabel(data, 1, -1)
1797 if (strlen(sdim))
1798 setscale /i y lo[%$sdim], hi[%$sdim], un[%$sdim], data
1799 snote = ReplaceStringByKey("AxisLabelY", snote, ax[%$sdim], "=", "\r")
1800 endif
1801
1802 sdim = GetDimLabel(data, 2, -1)
1803 if (strlen(sdim))
1804 setscale /i z lo[%$sdim], hi[%$sdim], un[%$sdim], data
1805 snote = ReplaceStringByKey("AxisLabelZ", snote, ax[%$sdim], "=", "\r")
1806 endif
1807
1808 string data_unit = un[%$kDataDimLabel]
1809 string data_label = ax[%$kDataDimLabel]
1810 string s
1811 variable def = (cmpstr(data_unit, "arb.") == 0) && (cmpstr(data_label, "value") == 0)
1812
1813 if (def)
1814 s = StringByKey("AxisLabelD", snote, "=", "\r")
1815 if (strlen(s) > 0)
1816 data_label = s
1817 def = 0
1818 endif
1819 s = StringByKey("AxisUnitD", snote, "=", "\r")
1820 if (strlen(s) > 0)
1821 data_unit = s
1822 def = 0
1823 endif
1824 endif
1825
1826 if (def)
1827 strswitch(NameOfWave(data))
1828 case "ScientaImage":
1829 case "ImageAngleDistribution":
1830 case "ScientaAngleDistribution":
1831 case "ScientaSpectrum":
1832 case "ImageEnergyDistribution":
1833 case "ScientaEnergyDistribution":
1834 data *= kDetectorSensitivity
1835 data_unit = "counts"
1836 data_label = "intensity"
1837 def = 0
1838 break
1839 case "SampleCurrent":
1840 case "RefCurrent":
1841 case "AuxCurrent":
1842 data_unit = "A"
1843 data_label = "current"
1844 def = 0
1845 break
1846 case "MachineCurrent":
1847 data_unit = "mA"
1848 data_label = "current"
1849 def = 0
1850 break
1851 endswitch
1852 endif
1853
1854 setscale d 0, 0, data_unit, data
1855 snote = ReplaceStringByKey("AxisLabelD", snote, data_label, "=", "\r")
1856 snote = ReplaceStringByKey("AxisUnitD", snote, data_unit, "=", "\r")
1857 snote = ReplaceStringByKey("Dataset", snote, NameOfWave(data), "=", "\r")
1858 note /k data, snote
1859 end
1860
1911 function /s psh5_load_reduced(ANickName, APathName, AFileName, reduction_func, reduction_param, [progress, nthreads])
1912 string ANickName
1913 string APathName
1914 string AFileName
1915 funcref adh5_default_reduction reduction_func
1916 string reduction_param
1917 variable progress
1918 variable nthreads
1919
1920 if (ParamIsDefault(progress))
1921 progress = 1
1922 endif
1923 if (ParamIsDefault(nthreads))
1924 nthreads = -1
1925 endif
1926
1927 dfref saveDF = GetDataFolderDFR()
1928
1929 // performance monitoring
1930 variable timerRefNum
1931 variable /g psh5_perf_secs
1932 timerRefNum = startMSTimer
1933
1934 variable fileID = psh5_open_file(ANickName, APathName, AFileName)
1935 string wavenames = ""
1936 if (fileID)
1937 dfref fileDF = GetDataFolderDFR()
1938 svar s_filepath
1939 svar s_scanpaths
1940 AFileName = s_filepath
1941 print "loading " + s_filepath + "\r"
1942
1943 variable ig = 0
1944 variable ng = ItemsInList(s_scanpaths)
1945 string scanpath
1946 string folder
1947 string positioners
1948 string positioner
1949 string positionerpath
1950
1951 scanpath = StringFromList(ig, s_scanpaths)
1952 folder = ReplaceString("/", scanpath, "")
1953 folder = ReplaceString(" ", folder, "")
1954 folder = PearlCleanupName(folder)
1955 setdatafolder fileDF
1956 newdatafolder /s /o $folder
1957 dfref dataDF = GetDataFolderDFR()
1958 positioners = psh5_load_scan_meta(fileID, scanpath)
1959 newdatafolder /s /o attr
1960 killwaves /a/z
1961 psh5_load_scan_attrs(fileID, scanpath)
1962 setdatafolder dataDF
1963 wave /t /z ScanWritables
1964 if (waveexists(ScanWritables) && (numpnts(ScanWritables) >= 1))
1965 positioner = ScanWritables[0]
1966 if (strlen(positioner) > 0)
1967 positionerpath = scanpath + "/" + positioner
1968 positionerpath = ReplaceString("//", positionerpath, "/")
1969 HDF5LoadData /O /Q /Z fileID, positionerpath
1970 endif
1971 endif
1972
1973 setdatafolder dataDF
1974 string datasets = psh5_list_scan_datasets(fileID, scanpath, include_regions=1)
1975 string dataset = select_dataset(datasets, "ScientaImage")
1976 wavenames = psh5_load_dataset_reduced(fileID, scanpath, dataset, reduction_func, reduction_param, progress=progress, nthreads=nthreads)
1977
1978 psh5_close_file(fileID)
1979 endif
1980
1981 if (timerRefNum >= 0)
1982 psh5_perf_secs = stopMSTimer(timerRefNum) / 1e6
1983 endif
1984
1985 setdatafolder saveDF
1986 return wavenames
1987 end
1988
1989
2040 function /s psh5_load_dataset_reduced(fileID, scanpath, datasetname, reduction_func, reduction_param, [progress, nthreads])
2041 variable fileID
2042 string scanpath
2043 string datasetname
2044 funcref adh5_default_reduction reduction_func
2045 string reduction_param
2046 variable progress
2047 variable nthreads
2048
2049 if (ParamIsDefault(progress))
2050 progress = 1
2051 endif
2052 if (ParamIsDefault(nthreads))
2053 nthreads = -1
2054 endif
2055
2056 dfref base_df = GetDataFolderDFR()
2057 variable result = 0
2058 string datasetpath
2059 string datawavename
2060 string wavenames = ""
2061
2062 datasetpath = scanpath + "/" + datasetname
2063 datasetpath = ReplaceString("//", datasetpath, "/")
2064 datawavename = StringFromList(ItemsInList(datasetpath, "/") - 1, datasetpath, "/")
2065
2066 string regionname
2067 string regionpath
2068 if (ItemsInList(datasetname, "/") >= 2)
2069 regionname = StringFromList(0, datasetname, "/")
2070 regionpath = ReplaceString("//", scanpath + "/" + regionname, "/")
2071 datasetname = RemoveListItem(0, datasetname, "/")
2072 NewDataFolder /o/s $regionname
2073 else
2074 regionname = ""
2075 regionpath = scanpath
2076 endif
2077
2078 STRUCT HDF5DataInfo di // Defined in HDF5 Browser.ipf.
2079 InitHDF5DataInfo(di)
2080 variable err = HDF5DatasetInfo(fileID, datasetpath, 0, di)
2081 if (err != 0)
2082 print "error accessing detector/data"
2083 result = -1
2084 return wavenames
2085 endif
2086 if (di.ndims < 2)
2087 print "error: rank of dataset < 2"
2088 result = -2
2089 return wavenames
2090 elseif (di.ndims < 3)
2091 progress = 0
2092 endif
2093
2094 variable idx, idy, idz, idt
2095 variable transpose = WhichListItem(datawavename, kTransposedDatasets) >= 0
2096 if (transpose)
2097 idx = 1
2098 idy = 0
2099 else
2100 idx = 0
2101 idy = 1
2102 endif
2103 idz = 2
2104 idt = 3
2105
2106 variable nx, ny, nz, nt, nzt
2107 nx = di.dims[idx]
2108 ny = di.dims[idy]
2109 nz = di.dims[idz]
2110 nt = di.dims[idt]
2111 // adjust singleton dimensions
2112 nz = max(nz, 1)
2113 nt = max(nt, 1)
2114 nzt = nz * nt
2115
2116 // load data image by image
2117 HDF5MakeHyperslabWave("slab", max(di.ndims, 4))
2118 wave slab
2119 slab[][%Start] = 0
2120 slab[][%Stride] = 1
2121 slab[][%Count] = 1
2122 slab[][%Block] = 1
2123 slab[idx][%Block] = nx
2124 slab[idy][%Block] = ny
2125
2126 // set up multi threading
2127 if (nthreads < 0)
2128 nthreads = ThreadProcessorCount
2129 endif
2130 if (nthreads > 0)
2131 variable threadGroupID = ThreadGroupCreate(nthreads)
2132 variable ithread
2133 for (ithread = 0; ithread < nthreads; ithread += 1)
2134 ThreadStart threadGroupID, ithread, reduce_slab_worker(reduction_func)
2135 endfor
2136 else
2137 make /n=(nzt) /df /free processing_folders
2138 endif
2139
2140 if (progress)
2141 display_progress_panel("HDF5 Import", "Loading data (step 1 of 2)...", nzt)
2142 endif
2143
2144 // create a template wave with the correct scales and labels
2145 make /n=(nx,ny) /d /o $datawavename
2146 wave template = $datawavename
2147 ps_set_dimlabels2(template, datawavename)
2148 ps_scale_dataset(template)
2149
2150 variable iz, it, izt
2151 string dfname
2152 variable iw, nw
2153 string sw
2154 make /n=0 /free /wave result_waves
2155
2156 izt = 0
2157 for (iz = 0; iz < nz; iz += 1)
2158 for (it = 0; it < nt; it += 1)
2159 // load hyperslab
2160 slab[idz][%Start] = iz
2161 slab[idt][%Start] = it
2162 dfname = "processing_" + num2str(izt)
2163 newdatafolder /s $dfname
2164 HDF5LoadData /O /Q /Z /SLAB=slab /N=slabdata fileID, datasetpath
2165
2166 // send to processing queue
2167 duplicate template, image
2168 variable /g r_index = iz
2169 variable /g s_index = it
2170 string /g func_param = reduction_param
2171
2172 if (nthreads > 0)
2173 WaveClear image
2174 ThreadGroupPutDF threadGroupID, :
2175 else
2176 processing_folders[izt] = GetDataFolderDFR()
2177 make /n=1/d profile1, profile2
2178 wave slabdata
2179 wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
2180 variable /g func_result = numpnts(reduced_waves)
2181 adh5_get_result_waves(reduced_waves, "redw_", 0)
2182 WaveClear slabdata, image, reduced_waves
2183 setdatafolder ::
2184 endif
2185
2186 izt += 1
2187 // progress window
2188 if (progress)
2189 if (update_progress_panel(izt))
2190 print "user abort"
2191 result = -4
2192 break
2193 endif
2194 endif
2195 endfor
2196 endfor
2197
2198 killwaves /z slab, slabdata, template
2199 if (progress)
2200 update_progress_panel(0, message="Processing data (step 2 of 2)...")
2201 endif
2202
2203 dfref dfr
2204 for (izt = 0; (izt < nzt) && (result == 0); izt += 1)
2205 if (nthreads > 0)
2206 do
2207 if (progress)
2208 if (update_progress_panel(izt))
2209 print "user abort"
2210 result = -4
2211 break
2212 endif
2213 endif
2214 dfr = ThreadGroupGetDFR(threadGroupID, 1000)
2215 if (DatafolderRefStatus(dfr) != 0)
2216 break
2217 endif
2218 while (1)
2219 else
2220 if (progress)
2221 if (update_progress_panel(izt))
2222 print "user abort"
2223 result = -4
2224 break
2225 endif
2226 endif
2227 dfr = processing_folders[izt]
2228 endif
2229
2230 if (result != 0)
2231 break
2232 endif
2233
2234 nvar rr = dfr:r_index
2235 nvar ss = dfr:s_index
2236 nvar func_result = dfr:func_result
2237
2238 if (func_result < 1)
2239 print "error during data reduction."
2240 result = -3
2241 break
2242 endif
2243
2244 if (numpnts(result_waves) == 0)
2245 redimension /n=(func_result) result_waves
2246 for (iw = 0; iw < func_result; iw += 1)
2247 sw = "redw_" + num2str(iw)
2248 wave profile = dfr:$sw
2249 sw = "ReducedData" + num2str(iw+1)
2250 make /n=(dimsize(profile, 0), nz, nt) /d /o $sw
2251 wave data = $sw
2252 setdimlabel 0, -1, $getdimlabel(profile, 0, -1), data
2253 setdimlabel 1, -1, $kScanDimLabel, data
2254 note data, note(profile)
2255 ps_scale_dataset(data)
2256 setscale /p x dimoffset(profile, 0), dimdelta(profile, 0), waveunits(profile, 0), data
2257 setscale d 0, 0, waveunits(profile, -1), data
2258 result_waves[iw] = data
2259 endfor
2260 endif
2261 for (iw = 0; iw < func_result; iw += 1)
2262 sw = "redw_" + num2str(iw)
2263 wave profile = dfr:$sw
2264 wave data = result_waves[iw]
2265 data[][rr][ss] = profile[p]
2266 endfor
2267 endfor
2268
2269 if (nthreads > 0)
2270 variable tstatus = ThreadGroupRelease(threadGroupID)
2271 if (tstatus == -2)
2272 print "error: thread did not terminate properly."
2273 result = -5
2274 endif
2275 else
2276 for (izt = 0; izt < nzt; izt += 1)
2277 KillDataFolder /Z processing_folders[izt]
2278 endfor
2279 endif
2280
2281 if (result == 0)
2282 nw = numpnts(result_waves)
2283 wavenames = ""
2284 for (iw = 0; iw < nw; iw += 1)
2285 wave data = result_waves[iw]
2286 if (nz == 1)
2287 redimension /n=(-1, 0, 0) data
2288 elseif (nt == 1)
2289 redimension /n=(-1, nz, 0) data
2290 endif
2291 wavenames += nameofwave(data) + ";"
2292 endfor
2293 endif
2294 if (progress)
2295 kill_progress_panel()
2296 endif
2297
2298 setdatafolder base_df
2299 return wavenames
2300 end
2301
2302 threadsafe static function reduce_slab_worker(reduction_func)
2303 funcref adh5_default_reduction reduction_func
2304 do
2305 // wait for job from main thread
2306 do
2307 dfref dfr = ThreadGroupGetDFR(0, 1000)
2308 if (DataFolderRefStatus(dfr) == 0)
2309 if (GetRTError(2))
2310 return 0 // no more jobs
2311 endif
2312 else
2313 break
2314 endif
2315 while (1)
2316
2317 // get input data
2318 wave slabdata = dfr:slabdata
2319 wave image = dfr:image
2320 svar func_param = dfr:func_param
2321 nvar rr = dfr:r_index
2322 nvar ss = dfr:s_index
2323
2324 // do the work
2325 newdatafolder /s outDF
2326 variable /g r_index = rr
2327 variable /g s_index = ss
2328 wave /wave reduced_waves = reduce_slab_image(slabdata, image, reduction_func, func_param)
2329 variable /g func_result = numpnts(reduced_waves)
2330
2331 // send output to queue and clean up
2332 adh5_get_result_waves(reduced_waves, "redw_", 0)
2333 WaveClear slabdata, image, reduced_waves
2334 ThreadGroupPutDF 0, :
2335 KillDataFolder dfr
2336 while (1)
2337
2338 return 0
2339 end
2340
2341 threadsafe static function /wave reduce_slab_image(slabdata, image, reduction_func, reduction_param)
2342 wave slabdata
2343 wave image
2344 funcref adh5_default_reduction reduction_func
2345 string reduction_param
2346
2347 // the multiplication by detector sensitivity assumes that we are loading a ScientaImage.
2348 image = slabdata[q][p][0][0] * kDetectorSensitivity
2349
2350 return reduction_func(image, reduction_param)
2351 end
2352
2367 function /s psh5_load_info(APathName, AFileName)
2368 string APathName
2369 string AFileName
2370
2371 dfref saveDF = GetDataFolderDFR()
2372 dfref fileDF = NewFreeDataFolder()
2373 setdatafolder fileDF
2374
2375 variable fileID
2376 string filepath
2377 string scanpaths
2378 variable nscans
2379 variable iscan
2380 string scanpath
2381 string info = ""
2382
2383 HDF5OpenFile /P=$APathName /R fileID as AFileName
2384 if (v_flag == 0)
2385 filepath = s_path + s_filename
2386 scanpaths = psh5_list_scans(fileID)
2387 nscans = ItemsInList(scanpaths)
2388 for (iscan = 0; iscan < nscans; iscan += 1)
2389 scanpath = StringFromList(iscan, scanpaths)
2390 info = info + scanpath + "\r"
2391 info = info + psh5_load_scan_info(fileID, scanpath)
2392 endfor
2393 HDF5CloseFile fileID
2394 endif
2395
2396 setdatafolder saveDF
2397 return info
2398 end
2399
2414 function /s psh5_load_scan_info(fileID, scanpath)
2415 variable fileID
2416 string scanpath
2417
2418 string info = ""
2419 string positions = ""
2420 string positioners = ""
2421 string readables = ""
2422 string detectors = ""
2423 string regions = ""
2424
2425 psh5_load_scan_meta(fileID, scanpath)
2426
2427 wave /z ScanDimensions
2428 wave /t /z ScanWritables
2429 wave /t /z ScanReadables
2430 wave /z ScanSteps
2431
2432 if (WaveExists(ScanSteps) && (numpnts(ScanSteps) >= 1))
2433 ScanSteps += 1
2434 positions = "positions = (" + wave2list(ScanSteps, "%u", ",") + ")"
2435 info = AddListItem(positions, info, "\r", inf)
2436 endif
2437 if (WaveExists(ScanWritables) && (numpnts(ScanWritables) >= 1))
2438 positioners = "positioners = " + twave2list(ScanWritables, ",")
2439 info = AddListItem(positioners, info, "\r", inf)
2440 endif
2441
2442 variable i, m, n
2443 string s
2444 if (WaveExists(ScanReadables) && (numpnts(ScanReadables) >= 1))
2445 readables = twave2list(ScanReadables, ",")
2446 n = ItemsInList(readables, ",")
2447 for (i = 0; i < n; i += 1)
2448 s = StringFromList(i, readables, ",")
2449 m = ItemsInList(s, "/")
2450 if (m > 1)
2451 s = StringFromList(m - 1, s, "/")
2452 endif
2453 if (WhichListItem(s, detectors, ",") < 0)
2454 detectors = AddListItem(s, detectors, ",", inf)
2455 endif
2456 endfor
2457 detectors = "detectors = " + detectors
2458 info = AddListItem(detectors, info, "\r", inf)
2459 endif
2460
2461 regions = psh5_list_scan_regions(fileID, scanpath)
2462 if (strlen(regions) > 0)
2463 regions = "regions = " + regions
2464 info = AddListItem(regions, info, "\r", inf)
2465 endif
2466
2467 return info
2468 end
2469
2473 static function /s twave2list(wt, sep)
2474 wave /t wt
2475 string sep
2476
2477 string list = ""
2478 variable n = numpnts(wt)
2479 variable i
2480 for (i = 0; i < n; i += 1)
2481 list = AddListItem(wt[i], list, sep, inf)
2482 endfor
2483
2484 return list
2485 end
2486
2490 static function /s wave2list(w, format, sep)
2491 wave w
2492 string format
2493 string sep
2494
2495 string list = ""
2496 variable n = numpnts(w)
2497 variable i
2498 string s
2499 for (i = 0; i < n; i += 1)
2500 sprintf s, format, w[i]
2501 list = AddListItem(s, list, sep, inf)
2502 endfor
2503
2504 return list
2505 end
kEnergyDimLabel
const string kEnergyDimLabel
Dimension label for the energy dispersive dimension of multi-dimensional datasets.
Definition: pearl-pshell-import.ipf:65
psh5_load_scan_preview
string psh5_load_scan_preview(variable fileID, string scanpath, variable set_scale=defaultValue, string pref_datasets=defaultValue)
load a preview dataset from an open PShell HDF5 file.
Definition: pearl-pshell-import.ipf:840
psh5_load_scan_attrs
string psh5_load_scan_attrs(variable fileID, string scanpath, variable attr_sets=defaultValue)
load attributes of a PShell scan group.
Definition: pearl-pshell-import.ipf:554
kTransposedDatasets
const string kTransposedDatasets
List of datasets that should be transposed upon loading.
Definition: pearl-pshell-import.ipf:84
psh5_load_scan_complete
string psh5_load_scan_complete(variable fileID, string scanpath, variable load_data=defaultValue, variable load_attr=defaultValue)
load all data of a selected scan from a PShell data file.
Definition: pearl-pshell-import.ipf:361
kScanDimLabel
const string kScanDimLabel
Dimension label for the scan dimension of multi-dimensional datasets.
Definition: pearl-pshell-import.ipf:71
PearlCleanupName
string PearlCleanupName(string name)
Definition: pearl-compat.ipf:47
kAngleDimLabel
const string kAngleDimLabel
Dimension label for the angle dispersive dimension of multi-dimensional datasets. ...
Definition: pearl-pshell-import.ipf:68
kDataDimLabel
const string kDataDimLabel
Dimension label for the data dimension.
Definition: pearl-pshell-import.ipf:75
psh5_load_preview
string psh5_load_preview(string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue, string pref_scans=defaultValue, string pref_datasets=defaultValue)
load a preview image from a PShell data file.
Definition: pearl-pshell-import.ipf:251
psh5_open_file
variable psh5_open_file(string ANickName, string APathName, string AFileName)
open a HDF5 file created by the PShell data acquisition program and prepare the data folder...
Definition: pearl-pshell-import.ipf:110
ps_scale_datasets
variable ps_scale_datasets()
set the dimension scales of loaded PShell Scienta datasets according to attributes.
Definition: pearl-pshell-import.ipf:1504
psh5_load_scan_meta
string psh5_load_scan_meta(variable fileID, string scanpath)
load metadata of a PShell scan group.
Definition: pearl-pshell-import.ipf:625
kScientaScalingDatasets
const string kScientaScalingDatasets
List of datasets that must be loaded to determine the axis scaling of a Scienta image.
Definition: pearl-pshell-import.ipf:81
psh5_list_scan_datasets
string psh5_list_scan_datasets(variable fileID, string scanpath, variable include_regions=defaultValue)
list datasets of a PShell scan group.
Definition: pearl-pshell-import.ipf:440
psh5_load_scan_data
string psh5_load_scan_data(variable fileID, string scanpath)
load all datasets of a PShell scan group.
Definition: pearl-pshell-import.ipf:514
kDetectorSensitivity
const variable kDetectorSensitivity
multiply scienta detector intensity by this value to get actual counts.
Definition: pearl-pshell-import.ipf:87
psh5_load_complete
string psh5_load_complete(string ANickName, string APathName, string AFileName, variable load_data=defaultValue, variable load_attr=defaultValue)
load everything from a PShell data file.
Definition: pearl-pshell-import.ipf:170
psh5_list_scans
string psh5_list_scans(variable fileID)
list scan groups of a PShell data file.
Definition: pearl-pshell-import.ipf:405
psh5_close_file
variable psh5_close_file(variable fileID)
close a HDF5 file opened by psh5_open_file.
Definition: pearl-pshell-import.ipf:140
kPreviewDatasets
const string kPreviewDatasets
List of preferred datasets to load for preview.
Definition: pearl-pshell-import.ipf:78