#pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IgorVersion = 6.1 #pragma ModuleName = PearlDataExplorer #pragma version = 1.50 #include "pearl-area-import" #include "pearl-area-profiles" #include "pearl-area-display" #include "pearl-pshell-import" #if exists("MFR_OpenResultFile") #include "pearl-matrix-import" #endif // copyright (c) 2013-16 Paul Scherrer Institut // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http:///www.apache.org/licenses/LICENSE-2.0 /// @file /// @brief preview and import panel for PEARL data /// @ingroup ArpesPackage /// /// /// preview and import panel for PEARL data: /// @arg area detector (HDF5) files from scienta analyser and prosilica cameras (if HDF5.xop is installed). /// @arg igor text files from s-scans and otf-scans. /// @arg pshell (HDF5) data files (if HDF5.xop is installed). /// @arg matrix STM files (if MatrixFileReader.xop is installed). /// @namespace PearlDataExplorer /// @brief preview and import panel for PEARL data /// /// PearlDataExplorer is declared in @ref pearl-data-explorer.ipf. static strconstant package_name = "pearl_explorer" static strconstant package_path = "root:packages:pearl_explorer:" static strconstant ks_filematch_adh5 = "*.h5" static strconstant ks_filematch_pshell = "psh*.h5" static strconstant ks_filematch_itx = "*.itx" static strconstant ks_filematch_mtrx = "*_mtrx" function pearl_data_explorer() init_package() load_prefs() execute /q/z "PearlDataExplorer()" end /// initialize the global variables of the data explorer. /// /// initializes the global variables and data folder for this procedure file /// must be called once before the panel is created /// warning: this function overwrites previous values static function init_package() dfref savefolder = GetDataFolderDFR() SetDataFolder root: newdatafolder /o/s packages newdatafolder /o/s $package_name if (exists("v_InitPanelDone") == 2) SetDataFolder savefolder return 0 endif make /o/n=0/t wtFiles make /o/n=0/i wSelectedFiles,wSelectedDatasets make /o/n=0/t wtDatasets make /o/n=0/t wtPositioners,wtDetectors make /o/n=0/i wSelectedPositioners,wSelectedDetectors make /o/n=(1,1) preview_image // preview 2D data make /o/n=0 preview_trace // preview 1D data make /o/n=0/t attr_names, attr_values, attr_filter, attr_filter_summary // persistent strings and variables. persistent = saved in preferences string /g s_filepath = "" // directory path to be listed string /g s_hdf_options = "" // recently used HDF5 load options string /g s_reduction_params = "" // recently used reduction parameters string /g s_preview_pvs = "" // semicolon-separated list of EPICS PVs to display in preview. // the list items can contain wildcards for StringMatch s_preview_pvs = "*OP:CURRENT*;*Stats*Total*;*CADC*" // non-persistent strings and variables string /g s_preview_file = "" // file or folder name of the current preview string /g s_preview_source = "" // data source, e.g. EPICS channel name, of the current preview string /g s_profiles_graph = "" // window name of the current preview if the data is two-dimensional string /g s_preview_trace_graph = "" // window name of the current preview if the data is one-dimensional string /g s_file_info = "" // description of selected file variable/g v_InitPanelDone = 1 SetDataFolder savefolder end static function save_prefs() // saves persistent package data to the preferences file // the data saved in the file are: data file path, attributes filter dfref saveDF = GetDataFolderDFR() string fullPath = SpecialDirPath("Packages", 0, 0, 0) fullPath += package_name NewPath/O/C/Q tempPackagePrefsPath, fullPath fullPath += ":preferences.pxp" SetDataFolder root:packages SetDataFolder $package_name string objects = "attr_filter;attr_filter_summary;s_filepath;s_hdf_options;s_reduction_params;s_preview_pvs" SaveData /O /Q /J=objects fullPath KillPath/Z tempPackagePrefsPath SetDataFolder saveDF end static function load_prefs() // loads persistent package data from the preferences file // the preferences file is an Igor packed experiment file in a special preferences folder dfref saveDF = GetDataFolderDFR() variable result = -1 setdatafolder root: NewDataFolder /O/S packages NewDataFolder /O/S $package_name dfref packageDF = GetDataFolderDFR() string fullPath = SpecialDirPath("Packages", 0, 0, 0) fullPath += package_name GetFileFolderInfo /Q /Z fullPath if (V_Flag == 0) // Disk directory exists? fullPath += ":preferences.pxp" GetFileFolderInfo /Q /Z fullPath if (V_Flag == 0) // Preference file exist? LoadData /O /R /Q fullPath result = 0 endif endif if (result == 0) svar /sdfr=packageDF filepath = s_filepath NewPath /O/Z pearl_explorer_filepath, filepath update_filelist() update_datasets() endif SetDataFolder saveDF return result end /// check whether a file can be imported by this module. /// /// the file type is determined by the extension of the file name. /// /// @return file type /// @arg 0 not a recognized file type /// @arg 1 PShell file (HDF5, name starts with psh_) /// @arg 2 area detector HDF5 file /// @arg 3 Igor text (itx) file /// @arg 4 Matrix STM file (*_mtrx) /// static function pearl_file_type(filename) string filename if (StringMatch(filename, ks_filematch_pshell)) return 1 elseif (StringMatch(filename, ks_filematch_adh5)) return 2 elseif (StringMatch(filename, ks_filematch_itx)) return 3 #if exists("MFR_OpenResultFile") elseif (StringMatch(filename, ks_filematch_mtrx)) return 4 #endif else return 0 endif end /// read a list of PEARL files from the file system /// /// wtFiles and wSelectedFiles in the package data folder are updated. /// only files for which pearl_file_type() returns non-zero are listed. /// static function update_filelist() dfref saveDF = GetDataFolderDFR() string all_files wave /t wtFiles = $(package_path + "wtFiles") wave wSelectedFiles = $(package_path + "wSelectedFiles") variable nn PathInfo pearl_explorer_filepath if (v_flag == 1) all_files = IndexedFile(pearl_explorer_filepath, -1, "????") nn = ItemsInList(all_files) else all_files = "" nn = 0 endif make /n=(nn) /t /free wtAllFiles wtAllFiles = StringFromList(p, all_files) Extract /o /t wtAllFiles, wtFiles, pearl_file_type(wtAllFiles[p]) Sort /A /R wtFiles, wtFiles redimension /n=(numpnts(wtFiles)) wSelectedFiles wSelectedFiles = 0 setdatafolder saveDF end static function update_datasets() // updates the list of imported datasets. // a dataset means any top-level data folder // which includes a string variable named pearl_explorer_import. dfref saveDF = GetDataFolderDFR() setdatafolder root: dfref rootdf = GetDataFolderDFR() setdatafolder $package_path dfref privatedf = GetDataFolderDFR() wave /t wtDatasets wave wSelectedDatasets variable maxdf = CountObjectsDFR(rootdf, 4) redimension /n=(maxdf) wtDatasets variable idf = 0 variable ndf = 0 string sdf do sdf = GetIndexedObjNameDFR(rootdf, 4, idf) if (strlen(sdf) >= 1) setdatafolder rootdf setdatafolder $sdf svar /z importer = pearl_explorer_import if (svar_exists(importer)) wtDatasets[ndf] = sdf ndf += 1 endif else break endif idf += 1 while(1) redimension /n=(ndf) wtDatasets, wSelectedDatasets wSelectedDatasets = 0 sort wtDatasets, wtDatasets setdatafolder saveDF end static function preview_file(filename) string filename dfref saveDF = GetDataFolderDFR() variable ft = pearl_file_type(filename) switch(ft) case 1: wave /z image = preview_pshell_file(filename) break case 2: wave /z image = preview_hdf_file(filename) break case 3: wave /z image = preview_itx_file(filename) break case 4: wave /z image = preview_mtrx_file(filename) break default: wave /z image = $"" endswitch if (WaveExists(image)) string graphname = show_preview_graph(image) // preset ELOG panel - if available if (exists("PearlElog#set_panel_attributes") == 6) string cmd sprintf cmd, "PearlElog#set_panel_attributes(\"\", \"File=%s\")", ParseFilePath(0, filename, ":", 1, 0) execute /Q/Z cmd if (strlen(graphname) > 0) sprintf cmd, "PearlElog#set_panel_graphs(\"\", \"%s\")", graphname execute /Q/Z cmd endif endif endif setdatafolder saveDF return 0 end /// load the preview of a PShell HDF5 file. /// /// the preview is an arbitrary detector image extracted from the file, see adh5_load_preview(). /// the preview is loaded to the preview_image wave in the pear_explorer data folder. /// /// the s_file_info string is updated with information about the scan dimensions. /// /// @param filename name of a file in the directory specified by the pearl_explorer_filepath path object. /// /// @return wave reference of the preview image /// static function /wave preview_pshell_file(filename) string filename dfref saveDF = GetDataFolderDFR() setdatafolder $package_path svar s_preview_file svar s_preview_source psh5_load_preview("preview_image", "pearl_explorer_filepath", filename) s_preview_file = filename s_preview_source = "" wave /z preview_image svar /z s_file_info if (! svar_exists(s_file_info)) string /g s_file_info endif if (strlen(s_preview_file) > 0) s_file_info = psh5_load_info("pearl_explorer_filepath", filename) else s_file_info = "" endif if (DataFolderExists("attr")) setdatafolder attr preview_attributes(GetDataFolderDFR()) setdatafolder :: endif setdatafolder saveDF return preview_image end /// load the preview of a PEARL HDF5 file. /// /// the preview is an arbitrary detector image extracted from the file, see adh5_load_preview(). /// the preview is loaded to the preview_image wave in the pear_explorer data folder. /// /// the s_file_info string is updated with information about the scan dimensions. /// /// @param filename name of a file in the directory specified by the pearl_explorer_filepath path object. /// /// @return wave reference of the preview image /// static function /wave preview_hdf_file(filename) string filename dfref saveDF = GetDataFolderDFR() setdatafolder $package_path svar s_preview_file svar s_preview_source adh5_load_preview("preview_image", "pearl_explorer_filepath", filename) s_preview_file = filename s_preview_source = "" wave /z preview_image svar /z s_file_info if (! svar_exists(s_file_info)) string /g s_file_info endif if (strlen(s_preview_file) > 0) s_file_info = adh5_load_info("pearl_explorer_filepath", filename) else s_file_info = "" endif if (DataFolderExists("attr")) setdatafolder attr preview_attributes(GetDataFolderDFR()) setdatafolder :: endif setdatafolder saveDF return preview_image end static function /wave preview_itx_file(filename) string filename dfref saveDF = GetDataFolderDFR() setdatafolder $package_path svar s_preview_file svar s_preview_source wave preview_image // note: some versions of PEARL data files save data to a new data folder, // and leave the newly created folder as the current folder. // the free data folder is used by those files which don't create their own data folder. // this is the new recommended behaviour dfref dataDF = newfreedatafolder() setdatafolder dataDF LoadWave /t/p=pearl_explorer_filepath/q filename s_preview_file = s_filename s_preview_source = "" preview_datafolder() preview_attributes(dataDF, include_datawaves=0) setdatafolder saveDF return preview_image end /// load the preview of a Matrix STM file. /// /// the preview is loaded to the preview_image wave in the pearl_explorer data folder. /// /// the s_file_info string is updated with information about the scan dimensions. /// /// this function requires the MatrixFileReader.xop and pearl-matrix-import.ipf to be loaded. /// otherwise it will return an empty wave reference. /// /// @param filename name of a file in the directory specified by the pearl_explorer_filepath path object. /// /// @return wave reference of the preview image. /// empty wave reference if the function failed. /// static function /wave preview_mtrx_file(filename) string filename #if exists("MFR_OpenResultFile") dfref saveDF = GetDataFolderDFR() setdatafolder $package_path variable /g V_MatrixFileReaderOverwrite = 1 variable /g V_MatrixFileReaderFolder = 0 variable /g V_MatrixFileReaderDouble = 0 svar s_preview_file svar s_preview_source string datanames string dataname datanames = mtrx_load_preview("preview", "pearl_explorer_filepath", filename) if (strlen(datanames) > 0) s_preview_file = filename dataname = StringFromList(0, datanames) wave data = $dataname duplicate /o $dataname, preview_image s_preview_source = StringByKey("Dataset", note(data), "=", "\r") svar /z s_file_info if (svar_exists(s_file_info)) s_file_info = "" endif variable i variable n = ItemsInList(datanames) string s for (i = 0; i < n; i += 1) s = StringFromList(i, datanames) killwaves /z $s endfor endif wave /z preview_image setdatafolder saveDF #else wave /z preview_image = $"" #endif return preview_image end static function extract_preview_image(data, preview) // extracts a preview image from a wave of arbitrary dimension wave data wave preview variable z1, z2 // extract image switch (WaveDims(data)) case 1: redimension /n=(numpnts(data)) preview preview = data[p] break case 2: redimension /n=(dimsize(data, 0), dimsize(data, 1)) preview preview = data break case 3: redimension /n=(dimsize(data, 0), dimsize(data, 1)) preview z1 = floor(DimSize(data, 2) / 2) z2 = z1 wave slab = ad_extract_slab(data, nan, nan, nan, nan, z1, z2, "", pscale=1) preview = slab break case 4: // not implemented endswitch switch (WaveDims(data)) case 4: case 3: case 2: setscale /p y dimoffset(data, 1), dimdelta(data, 1), waveunits(data, 1), preview case 1: setscale /p x dimoffset(data, 0), dimdelta(data, 0), waveunits(data, 0), preview setscale d 0, 0, waveunits(data, -1), preview endswitch end static function preview_dataset(datasetname) string datasetname // name of a data folder under root dfref saveDF = GetDataFolderDFR() if (!DataFolderExists("root:" + datasetname)) return -1 endif setdatafolder root: setdatafolder $datasetname dfref datadf = GetDataFolderDFR() wave /z data setdatafolder $package_path svar s_preview_file svar s_preview_source wave preview_image if (WaveExists(data)) s_preview_file = datasetname s_preview_source = "" extract_preview_image(data, preview_image) show_preview_graph(preview_image) else preview_image = nan s_preview_file = datasetname setdatafolder datadf preview_datafolder() show_preview_graph(preview_image) endif // attributes setdatafolder datadf if (DataFolderExists("attr")) setdatafolder attr preview_attributes(GetDataFolderDFR()) else preview_attributes(GetDataFolderDFR(), include_datawaves=0) endif setdatafolder saveDF return 0 end static function preview_datafolder() // preview data in the current data folder dfref saveDF = GetDataFolderDFR() setdatafolder $package_path svar s_preview_file svar s_preview_source svar s_preview_pvs wave preview_image setdatafolder saveDF // select a wave to display // consider only double-precision waves, i.e. ignore text and other special waves // filter by matching PV name to s_preview_pvs string d_names = WaveList("*", ";", "DP:1") variable nw = ItemsInList(d_names, ";") variable npv = ItemsInList(s_preview_pvs, ";") variable iw, ipv string wname, wnote, pv_name, pv_match for (iw = 0; iw < nw; iw += 1) wname = StringFromList(iw, d_names, ";") wnote = note($wname) pv_name = StringByKey("PV", wnote, "=", "\r") // find matching data wave by PV name for (ipv = 0; ipv < npv; ipv += 1) pv_match = StringFromList(ipv, s_preview_pvs) if (StringMatch(pv_name, pv_match)) wave data = $wname s_preview_source = pv_name extract_preview_image(data, preview_image) preview_setscale_x(data, preview_image) npv = 0 nw = 0 endif endfor endfor setdatafolder saveDF end static function preview_setscale_x(data, preview) // sets the approximate x scale of OTF data. // requires an Axis1 tag with name of x wave in the wave note. // if any of these conditions is true, the function does not change the scaling: // 1) Axis1 tag or referenced wave is missing. // 2) preview wave is not set to point scaling. // 3) x wave is not monotonic (90% of the steps in the same direction). wave data wave preview if ((DimOffset(preview, 0) == 0) && (DimDelta(preview, 0) == 1)) string xname = StringByKey("Axis1", note(data), "=", "\r") wave /z xwave = $xname if (WaveExists(xwave)) // check for monotonicity variable monotonic = 0 duplicate /free xwave, xdiff differentiate /p xwave /D=xdiff duplicate /free xdiff, xflag xflag = xdiff > 0 monotonic = sum(xflag) > numpnts(xwave) * 0.9 xflag = xdiff < 0 monotonic = monotonic || (sum(xflag) > numpnts(xwave) * 0.9) if (monotonic) setscale /i x xwave[0], xwave[numpnts(xwave)-1], waveunits(xwave, -1), preview endif endif endif end static function preview_attributes(attr_folder, [dest_folder, attr_filter, include_datawaves, include_infowaves]) // copies the first elements of attributes in the specified folder to the preview waves // by default, all existing attributes are copied // if a text wave attr_filter exists in the pear_explorer folder, only the attributes referenced therein are copied // to set up a filter, duplicate the attr_names wave of a template dataset, and remove unwanted items dfref attr_folder // data folder which contains the attribute waves dfref dest_folder // destination folder. the output is written to the attr_names and attr_values waves // default = package folder wave /t attr_filter // list of attributes allowed in the output // default = use attr_filter of package folder variable include_datawaves // 1 (default) = include data waves (any numeric wave which has a PV=name note) // 0 = don't include attributes from data waves variable include_infowaves // 1 (default) = include attributes from info waves (IN, ID, IV, IU) // 0 = don't include attributes from info waves dfref saveDF = GetDataFolderDFR() setdatafolder $package_path if (ParamIsDefault(dest_folder)) dest_folder = GetDataFolderDFR() // package folder endif if (ParamIsDefault(attr_filter)) wave /t /z attr_filter endif if (ParamIsDefault(include_datawaves)) include_datawaves = 1 endif if (ParamIsDefault(include_infowaves)) include_infowaves = 1 endif setdatafolder dest_folder wave /t /z attr_names, attr_values if (!WaveExists(attr_names) || !WaveExists(attr_values)) make /n=(1) /o /t attr_names, attr_values endif attr_names = "" attr_values = "" string /g s_attr_folder = GetDataFolder(1, attr_folder) setdatafolder attr_folder wave /t /z IN wave /t /z ID wave /t /z IV wave /t /z IU // compile list of attributes variable nattr // destination attributes variable iattr variable ninfo // info wave elements variable iinfo variable nw // attribute waves variable iw string sw string ss if (WaveExists(IN) && include_infowaves) ninfo = numpnts(IN) else ninfo = 0 endif if (include_datawaves) string waves = WaveList("*", ";", "") string exceptions = "ID;IN;IU;IV" waves = RemoveFromList(exceptions, waves) nw = ItemsInList(waves, ";") else nw = 0 endif if (WaveExists(attr_filter) && (numpnts(attr_filter) >= 1)) nattr = numpnts(attr_filter) redimension /n=(nattr) attr_names attr_names = attr_filter else if(ninfo > 0) redimension /n=(ninfo) attr_names attr_names = SelectString(strlen(ID[p]) >= 0, IN[p], ID[p]) // use ID unless empty endif nattr = ninfo + nw iattr = ninfo redimension /n=(nattr) attr_names for (iw = 0; iw < nw; iw +=1 ) sw = StringFromList(iw, waves, ";") ss = StringByKey("PV", note($sw), "=", "\r") FindValue /text=sw attr_names if ((v_value < 0) && (strlen(ss) >= 0)) attr_names[iattr] = sw iattr += 1 endif endfor nattr = iattr endif redimension /n=(nattr) attr_names, attr_values sort attr_names, attr_names // look up attribute values for (iattr = 0; iattr < nattr; iattr += 1) sw = attr_names[iattr] // try info waves if (ninfo > 0) FindValue /text=sw ID if (v_value >= 0) attr_values[iattr] = IV[v_value] endif FindValue /text=sw IN if (v_value >= 0) attr_values[iattr] = IV[v_value] endif endif // override from attribute wave if existent if (nw > 0) switch (WaveType($sw, 1)) case 1: // numeric wave /z w = $sw if (WaveExists(w) && (numpnts(w) >= 1)) sprintf ss, "%g", w[0] attr_values[iattr] = ss endif break case 2: // text wave /t/z wt = $sw if (WaveExists(wt) && (numpnts(wt) >= 1)) attr_values[iattr] = wt[0] endif break endswitch endif endfor setdatafolder saveDF end static function display_dataset(datasetname) // displays the graph of a loaded dataset in its own window string datasetname // name of a data folder under root dfref saveDF = GetDataFolderDFR() if (!DataFolderExists("root:" + datasetname)) return -1 endif setdatafolder root: setdatafolder $datasetname dfref datadf = GetDataFolderDFR() wave /z data if (!WaveExists(data)) wave /z data = data1 endif if (WaveExists(data)) switch(WaveDims(data)) case 2: ad_display_profiles(data) break case 3: ad_display_slice(data) ad_brick_slicer(data) break endswitch endif setdatafolder saveDF return 0 end function test_attributes_notebook() dfref df = GetDataFolderDFR() wave /t /sdfr=df attr_names wave /t /sdfr=df attr_values attributes_notebook(attr_names, attr_values, GetDataFolder(0)) end static function attributes_notebook(attr_names, attr_values, title) wave /t attr_names wave /t attr_values string title dfref saveDF = GetDataFolderDFR() setdatafolder $package_path wave /t/z attr_filter, attr_filter_summary string name = CleanupName("nb_" + title[0,28], 0) if (WinType(name) == 5) Notebook $name selection={startOfFile, endOfFile} Notebook $name text="" else NewNotebook /F=1 /K=1 /N=$name as title GetWindow $name wsize v_right = v_left + 260 v_bottom = v_top + 360 MoveWindow /W=$name v_left, v_top, v_right, v_bottom Notebook $name tabs={2*72} endif // summary if (WaveExists(attr_filter_summary) && (numpnts(attr_filter_summary) >= 1)) notebook $name fStyle=1, text="Summary\r\r" notebook $name fStyle=0 notebook_add_attributes(name, attr_filter_summary, attr_names, attr_values) notebook $name text="\r" endif // all attributes notebook $name fStyle=1, text="All Attributes\r\r" notebook $name fStyle=0 notebook_add_attributes(name, $"", attr_names, attr_values) notebook $name selection={startOfFile,startOfFile}, findText={"",1} setdatafolder saveDF end static function notebook_add_attributes(notebook_name, attr_filter, attr_names, attr_values) string notebook_name wave /t /z attr_filter wave /t attr_names wave /t attr_values variable nw = numpnts(attr_names) variable iw string sw string ss variable do_filter = WaveExists(attr_filter) for (iw = 0; iw < nw; iw += 1) if (do_filter) sw = attr_names[iw] FindValue /text=sw attr_filter else v_value = 0 endif if (v_value >= 0) sprintf ss, "%s\t%s\r", attr_names[iw], attr_values[iw] notebook $notebook_name text=ss endif endfor end static function /s show_preview_graph(data, [xdata]) // displays a preview of one- or two-dimensional data wave data // data to be displayed. must either one-dimensional or two-dimensional wave xdata // positions on x axis dfref saveDF = GetDataFolderDFR() setdatafolder $package_path svar s_profiles_graph svar s_preview_file svar s_preview_source svar s_preview_trace_graph if ((strlen(s_profiles_graph) > 0) && (WinType(s_profiles_graph) == 1)) KillWindow $s_profiles_graph endif if ((strlen(s_preview_trace_graph) > 0) && (WinType(s_preview_trace_graph) == 1)) KillWindow $s_preview_trace_graph endif string graphname if (wavedims(data) == 2) s_profiles_graph = ad_display_profiles(data) ModifyGraph /w=$s_profiles_graph /z wbRGB=(48640,56832,60160) graphname = s_profiles_graph elseif (wavedims(data) == 1) duplicate /o data, preview_trace if (!ParamIsDefault(xdata)) duplicate /o xdata, preview_trace_x else duplicate /o data, preview_trace_x preview_trace_x = x setscale d 0, 0, WaveUnits(data, 0), preview_trace_x endif s_preview_trace_graph = display_preview_trace(preview_trace_x, preview_trace) ModifyGraph /w=$s_preview_trace_graph wbRGB=(48640,56832,60160) graphname = s_preview_trace_graph else return "" endif string title = "Preview " + s_preview_file if (strlen(s_preview_source) > 0) title = title + " (" + s_preview_source[0,31] + ")" endif dowindow /f/t $graphname, title setdatafolder saveDF return graphname end static function /s display_preview_trace(xtrace, ytrace) wave xtrace wave ytrace display /n=pearl_explorer_1d /k=1 ytrace vs xtrace as "Preview" string graphname = s_name ModifyGraph /w=$graphname rgb[0]=(0,0,0) ModifyGraph /w=$graphname grid=2 ModifyGraph /w=$graphname mirror=1 ModifyGraph /w=$graphname minor=1 ModifyGraph /w=$graphname axThick=0.5 ModifyGraph /w=$graphname gridRGB=(52224,52224,52224) ModifyGraph /w=$graphname gridHair=0 ModifyGraph /w=$graphname tick=0 ModifyGraph /w=$graphname btLen=4 // axis labels string labels = note(ytrace) string lab lab = StringByKey("AxisLabelX", labels, "=", "\r") if (!strlen(lab)) lab = "X" endif Label /w=$graphname bottom lab + " (\\U)" lab = StringByKey("AxisLabelD", labels, "=", "\r") if (!strlen(lab)) lab = "value" endif Label /w=$graphname left lab + " (\\U)" return s_name end static function load_selected_files([options]) string options dfref saveDF = GetDataFolderDFR() setdatafolder $package_path wave wSelectedFiles wave/t wtFiles variable nn = numpnts(wSelectedFiles) variable ii for (ii = 0; ii < nn; ii += 1) if (wSelectedFiles[ii]) if (ParamIsDefault(options)) load_file(wtFiles[ii]) else load_file(wtFiles[ii], options=options) endif endif endfor update_datasets() setdatafolder saveDF end static function load_file(filename, [options]) string filename string options dfref saveDF = GetDataFolderDFR() variable ft = pearl_file_type(filename) switch(ft) case 1: if (ParamIsDefault(options)) load_pshell_file(filename) else load_pshell_file(filename, options=options) endif break case 2: if (ParamIsDefault(options)) load_hdf_file(filename) else load_hdf_file(filename, options=options) endif break case 3: load_itx_file(filename) break case 4: load_mtrx_file(filename) break default: break endswitch setdatafolder saveDF end static function prompt_hdf_options(options) string &options string mode = StringByKey("mode", options, ":", ";") string reduction_func = StringByKey("reduction_func", options, ":", ";") string modes = "load_reduced" string reduction_functions = adh5_list_reduction_funcs() if (strlen(mode) == 0) mode = StringFromList(0, modes, ";") endif if (strlen(reduction_func) == 0) reduction_func = StringFromList(0, reduction_functions, ";") endif prompt mode, "Mode", popup, modes prompt reduction_func, "Reduction Function", popup, reduction_functions doprompt "HDF5 Loading Options", mode, reduction_func if (v_flag == 0) options = ReplaceStringByKey("mode", options, mode, ":", ";") options = ReplaceStringByKey("reduction_func", options, reduction_func, ":", ";") endif return v_flag // 0 = OK, 1 = cancel end /// prototype for prompting for processing function parameters. /// /// the function should prompt the user for function parameters, /// and update the param argument if the user clicked OK. /// returns 0 if the user clicked OK, 1 if the user cancelled. /// /// prompt functions must have the same name as the corresponding reduction function /// with the prefix "prompt_". /// be aware of the limited length of function names in Igor. /// /// this function is a prototype. it does nothing but returns OK. /// function prompt_default_process(param) string ¶m return 0 end function prompt_func_params(func_name, func_param) string func_name string &func_param string prompt_name = "prompt_" + func_name if (exists(prompt_name) == 6) funcref prompt_default_process prompt_func = $prompt_name return prompt_func(func_param) else // ignore missing prompt function return 0 endif end static function /df load_pshell_file(filename, [options]) string filename string options dfref saveDF = GetDataFolderDFR() string nickname = ad_suggest_foldername(filename) string loaded_filename = "" if (ParamIsDefault(options)) loaded_filename = psh5_load_complete(nickname, "pearl_explorer_filepath", filename) else if (strlen(options) == 0) svar pref_options = $(package_path + "s_hdf_options") options = pref_options if (prompt_hdf_options(options) == 0) // OK pref_options = options else // cancel options = "" endif endif string mode = StringByKey("mode", options, ":", ";") strswitch(mode) case "load_reduced": string reduction_func = StringByKey("reduction_func", options, ":", ";") svar pref_params = $(package_path + "s_reduction_params") string reduction_params = pref_params if (prompt_func_params(reduction_func, reduction_params) == 0) pref_params = reduction_params print reduction_func, reduction_params psh5_load_reduced(nickname, "pearl_explorer_filepath", filename, $reduction_func, reduction_params) svar s_filepath loaded_filename = s_filepath endif break endswitch endif dfref dataDF if (strlen(loaded_filename) > 0) setdatafolder $("root:" + nickname) dataDF = GetDataFolderDFR() string /g pearl_explorer_import = "load_pshell_file" endif setdatafolder saveDF return dataDF end static function /df load_hdf_file(filename, [options]) string filename string options dfref saveDF = GetDataFolderDFR() string nickname = ad_suggest_foldername(filename) string loaded_filename = "" if (ParamIsDefault(options)) loaded_filename = adh5_load_complete(nickname, "pearl_explorer_filepath", filename) else if (strlen(options) == 0) svar pref_options = $(package_path + "s_hdf_options") options = pref_options if (prompt_hdf_options(options) == 0) // OK pref_options = options else // cancel options = "" endif endif string mode = StringByKey("mode", options, ":", ";") strswitch(mode) case "load_reduced": string reduction_func = StringByKey("reduction_func", options, ":", ";") svar pref_params = $(package_path + "s_reduction_params") string reduction_params = pref_params if (prompt_func_params(reduction_func, reduction_params) == 0) pref_params = reduction_params print reduction_func, reduction_params loaded_filename = adh5_load_reduced(nickname, "pearl_explorer_filepath", filename, $reduction_func, reduction_params) endif break endswitch endif dfref dataDF if (strlen(loaded_filename) > 0) setdatafolder $("root:" + nickname) dataDF = GetDataFolderDFR() string /g pearl_explorer_import = "load_hdf_file" endif setdatafolder saveDF return dataDF end static function /df load_itx_file(filename, [options]) string filename string options dfref saveDF = GetDataFolderDFR() string nickname = itx_suggest_foldername(filename) if (ParamIsDefault(options)) options = "" endif setdatafolder root: newdatafolder /s/o $("root:" + nickname) dfref dataDF = GetDataFolderDFR() // note: some versions of PEARL data files save data to a new data folder, // and leave the newly created folder as the current folder. // the free data folder is used by those files which don't create their own data folder. // this is the new recommended behaviour LoadWave /t/p=pearl_explorer_filepath/q filename svar waves = s_wavenames dfref actDF = GetDataFolderDFR() if (v_flag > 0) string /g pearl_explorer_import = "load_itx_file" endif if (!DataFolderRefsEqual(actDF, dataDF)) // the file created its own data folder. // let's kill the pre-allocated folder setdatafolder dataDF if (ItemsInList(WaveList("*", ";", ""), ";") == 0) killdatafolder /z dataDF endif endif setdatafolder saveDF return actDF end /// load a matrix (STM) data file /// /// static function /df load_mtrx_file(filename, [options]) string filename string options dfref saveDF = GetDataFolderDFR() dfref dataDF = $"" #if exists("MFR_OpenResultFile") setdatafolder root: string datasets = "" datasets = mtrx_load_file("pearl_explorer_filepath", filename) if (strlen(datasets) > 0) string /g pearl_explorer_import = "load_mtrx_file" string s1 = StringFromList(0, datasets) wave w1 = $s1 dataDF = GetWavesDataFolderDFR(w1) endif #endif setdatafolder saveDF return dataDF end function /s itx_suggest_foldername(filename, [ignoredate,sourcename,unique]) // suggests the name of a data folder based on a file name // if the file name follows the naming convention source-date-index.extension, // the function tries to generate the nick name as source_date_index. // otherwise it's just a cleaned up version of the file name. string filename // file name, including extension. can also include a folder path (which is ignored) // the extension is currently ignored, but may be used later to select the parent folder variable ignoredate // if non-zero, the nick name will not include the date part // defaults to zero string sourcename // nick name of the data source // the function tries to detect the source from the file name // this option can be used to override auto-detection // allowed values: sscan, otf variable unique // if non-zero, the resulting name is made a unique data folder name in the current data folder // defaults to zero if (ParamIsDefault(ignoredate)) ignoredate = 0 endif if (ParamIsDefault(unique)) unique = 0 endif string basename = ParseFilePath(3, filename, ":", 0, 0) string extension = ParseFilePath(4, filename, ":", 0, 0) string nickname string autosource if (strsearch(basename, "X03DA_PC", 0, 2) >= 0) autosource = "sscan" basename = ReplaceString("_", basename, "-") ignoredate = 1 elseif (strsearch(basename, "otf", 0, 2) >= 0) autosource = "otf" endif if (ParamIsDefault(sourcename)) sourcename = autosource endif variable nparts = ItemsInList(basename, "-") if (nparts >= 3) string datepart = StringFromList(nparts - 2, basename, "-") string indexpart = StringFromList(nparts - 1, basename, "-") if (ignoredate) sprintf nickname, "%s_%s", sourcename, indexpart else sprintf nickname, "%s_%s_%s", sourcename, datepart, indexpart endif else nickname = CleanupName(basename, 0) endif if (unique && CheckName(nickname, 11)) nickname = UniqueName(nickname + "_", 11, 0) endif return nickname end Window PearlDataExplorer() : Panel PauseUpdate; Silent 1 // building window... NewPanel /K=1 /W=(800,0,1530,444) as "PEARL Data Explorer" ModifyPanel cbRGB=(48640,56832,60160) GroupBox gb_filepath,pos={8,4},size={224,52},title="file system folder" TitleBox tb_filepath,pos={20,24},size={174,20},frame=2 TitleBox tb_filepath,variable=root:packages:pearl_explorer:s_filepath,fixedSize=1 Button b_browse_filepath,pos={200,24},size={20,20},proc=PearlDataExplorer#bp_browse_filepath,title="..." Button b_browse_filepath,fColor=(65280,48896,32768) GroupBox gb_prefs,pos={240,4},size={58,52},title="prefs",help={"explorer package preferences"} Button b_save_prefs,pos={252,20},size={32,17},proc=PearlDataExplorer#bp_save_prefs,title="save" Button b_save_prefs,help={"save preferences of the data explorer package (data file path, attributes filter)"} Button b_save_prefs,fColor=(65280,48896,32768) Button b_load_prefs,pos={252,36},size={32,17},proc=PearlDataExplorer#bp_load_prefs,title="load" Button b_load_prefs,help={"load preferences of the data explorer package"} Button b_load_prefs,fColor=(65280,48896,32768) GroupBox gb_filelist,pos={8,64},size={224,372},title="data files" ListBox lb_files,pos={20,84},size={200,212},proc=PearlDataExplorer#lbp_filelist ListBox lb_files,listWave=root:packages:pearl_explorer:wtFiles ListBox lb_files,selWave=root:packages:pearl_explorer:wSelectedFiles,row= 11,mode= 4 TitleBox tb_file_info,pos={20,300},size={198,78},frame=2,fixedSize=1 TitleBox tb_file_info,variable= root:packages:pearl_explorer:s_file_info Button b_update_filelist,pos={20,386},size={60,20},proc=PearlDataExplorer#bp_update_filelist,title="update list" Button b_update_filelist,fColor=(65280,48896,32768) CheckBox cb_file_preview,pos={84,390},size={60,20},title="preview" CheckBox cb_file_preview,help={"enable/disable automatic preview window when selecting a data file"} CheckBox cb_file_preview,value=1 Button b_file_prev,pos={176,386},size={20,20},proc=PearlDataExplorer#bp_file_prev,title="\\W646" Button b_file_prev,help={"previous file"} Button b_file_prev,fColor=(65280,48896,32768) Button b_file_next,pos={200,386},size={20,20},proc=PearlDataExplorer#bp_file_next,title="\\W649" Button b_file_next,help={"next file"} Button b_file_next,fColor=(65280,48896,32768) Button b_load_files,pos={20,410},size={76,20},proc=PearlDataExplorer#bp_load_files,title="load complete" Button b_load_files,help={"load the complete contents from the selected files"} Button b_load_files,fColor=(65280,48896,32768) Button b_load_files_opt,pos={100,410},size={76,20},proc=PearlDataExplorer#bp_load_files_opt,title="load reduced" Button b_load_files_opt,help={"load data from the selected files with options (reduced dimensions)"} Button b_load_files_opt,fColor=(65280,48896,32768) // datasets group GroupBox gb_datasets,pos={240,64},size={224,372},title="datasets" ListBox lb_datasets,pos={252,84},size={200,300},proc=PearlDataExplorer#lbp_datasets,help={"list of loaded datasets"} ListBox lb_datasets,listWave=root:packages:pearl_explorer:wtDatasets ListBox lb_datasets,selWave=root:packages:pearl_explorer:wSelectedDatasets,mode= 1 ListBox lb_datasets,selRow= -1 Button b_update_datasets,pos={252,386},size={60,20},proc=PearlDataExplorer#bp_update_datasets,title="update list" Button b_update_datasets,help={"update the list of datasets"} Button b_update_datasets,fColor=(65280,48896,32768) CheckBox cb_dataset_preview,pos={316,390},size={60,20},title="preview" CheckBox cb_dataset_preview,help={"enable/disable automatic preview window when selecting a dataset"} CheckBox cb_dataset_preview,value=0 Button b_dataset_prev,pos={408,386},size={20,20},proc=PearlDataExplorer#bp_dataset_prev,title="\\W646" Button b_dataset_prev,help={"goto previous dataset"} Button b_dataset_prev,fColor=(65280,48896,32768) Button b_dataset_next,pos={432,386},size={20,20},proc=PearlDataExplorer#bp_dataset_next,title="\\W649" Button b_dataset_next,help={"goto next dataset"} Button b_dataset_next,fColor=(65280,48896,32768) Button b_dataset_folder,pos={252,410},size={50,20},proc=PearlDataExplorer#bp_dataset_folder,title="goto DF" Button b_dataset_folder,help={"set the current data folder of the selected dataset"} Button b_dataset_folder,fColor=(65280,48896,32768) Button b_dataset_display,pos={306,410},size={50,20},proc=PearlDataExplorer#bp_dataset_display,title="display" Button b_dataset_display,help={"display the selected dataset in its own window"} Button b_dataset_display,fColor=(65280,48896,32768) GroupBox gb_preview,pos={472,4},size={250,52},title="preview" TitleBox tb_preview_file,pos={484,24},size={226,20},frame=2 TitleBox tb_preview_file,variable=root:packages:pearl_explorer:s_preview_file,fixedSize=1 GroupBox gb_attributes,pos={472,64},size={250,372},title="attributes" Button b_attr_notebook,pos={484,386},size={60,20},proc=PearlDataExplorer#bp_attr_notebook,title="notebook" Button b_attr_notebook,help={"show attribute list in a notebook"} Button b_attr_notebook,fColor=(65280,48896,32768) String fldrSav0= GetDataFolder(1) SetDataFolder root:packages:pearl_explorer: Edit/W=(484,84,710,384)/HOST=# attr_names,attr_values ModifyTable format(Point)=1,width(Point)=0,width(attr_names)=103,width(attr_values)=103 ModifyTable statsArea=85 SetDataFolder fldrSav0 RenameWindow #,T0 SetActiveSubwindow ## EndMacro static function bp_load_prefs(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up load_prefs() break case -1: // control being killed break endswitch return 0 End static function bp_save_prefs(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up save_prefs() break case -1: // control being killed break endswitch return 0 End static function bp_browse_filepath(ba) : ButtonControl STRUCT WMButtonAction &ba dfref saveDF = GetDataFolderDFR() switch( ba.eventCode ) case 2: // mouse up PathInfo /S pearl_explorer_filepath NewPath /M="select data file folder" /O/Z pearl_explorer_filepath if (v_flag == 0) PathInfo /S pearl_explorer_filepath svar filepath = $(package_path + "s_filepath") filepath = s_path update_filelist() endif break case -1: // control being killed break endswitch setdatafolder saveDF return 0 End static function bp_update_filelist(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up update_filelist() break case -1: // control being killed break endswitch return 0 End static function bp_load_files(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up load_selected_files() break case -1: // control being killed break endswitch return 0 End static function bp_load_files_opt(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up load_selected_files(options="") break case -1: // control being killed break endswitch return 0 End static function bp_file_next(ba) : ButtonControl STRUCT WMButtonAction &ba dfref saveDF = GetDataFolderDFR() switch( ba.eventCode ) case 2: // mouse up setdatafolder $package_path wave /t wtFiles wave wSelectedFiles FindValue /i=1 wSelectedFiles v_value += 1 if (v_value >= numpnts(wtFiles)) v_value = min(numpnts(wtFiles) - 1, 0) endif wSelectedFiles = p == v_value if (v_value >= 0) variable ifile = v_value ControlInfo /W=PearlDataExplorer cb_file_preview if (v_value) preview_file(wtFiles[ifile]) endif endif break case -1: // control being killed break endswitch setdatafolder saveDF return 0 End static function bp_file_prev(ba) : ButtonControl STRUCT WMButtonAction &ba dfref saveDF = GetDataFolderDFR() switch( ba.eventCode ) case 2: // mouse up setdatafolder $package_path wave /t wtFiles wave wSelectedFiles FindValue /i=1 wSelectedFiles v_value -= 1 if (v_value < 0) v_value = numpnts(wtFiles) - 1 endif wSelectedFiles = p == v_value if (v_value >= 0) variable ifile = v_value ControlInfo /W=PearlDataExplorer cb_file_preview if (v_value) preview_file(wtFiles[ifile]) endif endif break case -1: // control being killed break endswitch setdatafolder saveDF return 0 End static function lbp_filelist(lba) : ListBoxControl STRUCT WMListboxAction &lba Variable row = lba.row Variable col = lba.col WAVE/T/Z listWave = lba.listWave WAVE/Z selWave = lba.selWave switch( lba.eventCode ) case -1: // control being killed break case 1: // mouse down if (selWave[row]) ControlInfo /W=PearlDataExplorer cb_file_preview if (v_value) preview_file(listWave[row]) endif endif break case 3: // double click break case 4: // cell selection case 5: // cell selection plus shift key break case 6: // begin edit break case 7: // finish edit break case 13: // checkbox clicked (Igor 6.2 or later) break endswitch return 0 End static function bp_update_datasets(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up update_datasets() break case -1: // control being killed break endswitch return 0 End static function bp_dataset_folder(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up ControlInfo /W=PearlDataExplorer lb_datasets if (v_value >= 0) setdatafolder $package_path wave /t wtDatasets string dataset = wtDatasets[v_value] string cmd sprintf cmd, "setdatafolder root:%s", PossiblyQuoteName(dataset) execute /q /z cmd cmd = "setdatafolder :scan1" execute /q /z cmd sprintf cmd, "setdatafolder %s", GetDataFolder(1) print cmd endif break case -1: // control being killed break endswitch return 0 End static function bp_dataset_display(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up ControlInfo /W=PearlDataExplorer lb_datasets if (v_value >= 0) setdatafolder $package_path wave /t wtDatasets string dataset = wtDatasets[v_value] display_dataset(dataset) endif break case -1: // control being killed break endswitch return 0 End static function bp_dataset_next(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up ControlInfo /W=PearlDataExplorer lb_datasets wave /t wtDatasets = $(s_datafolder + s_value) v_value += 1 if (v_value >= numpnts(wtDatasets)) v_value = min(0, numpnts(wtDatasets) - 1) endif ListBox lb_datasets win=PearlDataExplorer, selRow=v_value if (v_value >= 0) variable ids = v_value ControlInfo /W=PearlDataExplorer cb_dataset_preview if (v_value) preview_dataset(wtDatasets[ids]) endif endif break case -1: // control being killed break endswitch return 0 End static function bp_dataset_prev(ba) : ButtonControl STRUCT WMButtonAction &ba switch( ba.eventCode ) case 2: // mouse up ControlInfo /W=PearlDataExplorer lb_datasets wave /t wtDatasets = $(s_datafolder + s_value) v_value -= 1 if (v_value < 0) v_value = max(-1, numpnts(wtDatasets) - 1) endif ListBox lb_datasets win=PearlDataExplorer, selRow=v_value if (v_value >= 0) variable ids = v_value ControlInfo /W=PearlDataExplorer cb_dataset_preview if (v_value) preview_dataset(wtDatasets[ids]) endif endif break case -1: // control being killed break endswitch return 0 End static function lbp_datasets(lba) : ListBoxControl STRUCT WMListboxAction &lba Variable row = lba.row Variable col = lba.col WAVE/T/Z listWave = lba.listWave WAVE/Z selWave = lba.selWave switch( lba.eventCode ) case -1: // control being killed break case 1: // mouse down if (row >= 0) ControlInfo /W=PearlDataExplorer cb_dataset_preview if (v_value) preview_dataset(listWave[row]) endif endif break case 3: // double click break case 4: // cell selection case 5: // cell selection plus shift key break case 6: // begin edit break case 7: // finish edit break case 13: // checkbox clicked (Igor 6.2 or later) break endswitch return 0 End static function bp_attr_notebook(ba) : ButtonControl STRUCT WMButtonAction &ba dfref saveDF = GetDataFolderDFR() switch( ba.eventCode ) case 2: // mouse up setdatafolder $package_path svar s_preview_file wave /t /z attr_names wave /t /z attr_values if (WaveExists(attr_names)) attributes_notebook(attr_names, attr_values, s_preview_file) endif break case -1: // control being killed break endswitch setdatafolder saveDF return 0 End