
Drag-and-drop loading of zipped ibw files

This procedure loads ibw files from a zipped file by dropping the zip onto the Igor window. The function LoadZippedIBW(filePath, fileName) can also be called from the command line or other functions. The zip is expanded into the current OS temp folder and the ibw files are deleted after loading. The code is 'dumb' and only works correctly for zip files with nothing else than ibw files in them, i.e., no support for other file types or a folder-structure. In pre-Igor 9 environments the zip is expanded via Tony's unzip script. Any suggestions for improvements are welcome. Supply your own PostProcessData() function if the waves need to be processed in some way (I use this for renaming and normalization).
Static Constant kVerbose = 0 Static Function BeforeFileOpenHook(refNum, fileNameStr, pathNameStr, fileTypeStr, fileCreatorStr, fileKind) Variable refNum, fileKind String fileNameStr, pathNameStr, fileTypeStr, fileCreatorStr If (StringMatch(fileNameStr,"*.zip")) PathInfo $pathNameStr LoadZippedIBW(S_path, fileNameStr) return 1 endif return 0 End //################################# Function LoadZippedIBW(filePath, fileName) String filePath, fileName Variable unzipError, i String tempFolder = SpecialDirPath("Temporary", 0, 0, 0) NewPath/O/Q tmpPath, tempFolder unzipError = unzipArchive(filePath+fileName, tempFolder) if (unzipError) Print "Could not unzip file " + fileName return -1 endif String tempFileList = IndexedFile(tmpPath, -1, "IGBW") if (strlen(tempFileList) > 0) for (i = 0; i < ItemsInList(tempFileList); i += 1) String currFile = StringFromList(i,tempFileList) LoadWave/O/Q/P=tmpPath currFile DeleteFile/Z/P=tmpPath currFile if (strlen(S_waveNames) > 0) Wave work = $StringFromList(0, S_waveNames) //PostProcessData(work, currFile) // post-process loaded wave endif endfor endif KillPath/Z tmpPath return 0 End //################################# // stripped down unzip procedure written by Tony Withers + Igor 9 support // https://www.wavemetrics.com/code-snippet/expand-zip-archive-platform-agnostic Static Function unzipArchive(archivePathStr, unzippedPathStr) String archivePathStr, unzippedPathStr GetFileFolderInfo /Q/Z archivePathStr if(V_Flag || V_isFile==0) printf "Could not find file %s\r", archivePathStr return -1 endif if(findlistItem(ParseFilePath(4, archivePathStr, ":", 0, 0), "zip;", ";", 0, 0) == -1) printf "%s doesn't appear to be a zip archive\r", ParseFilePath(0, archivePathStr, ":", 1, 0) return -1 endif #if(IgorVersion() >= 9) // in Igor 9 just use unZip and quit unzippedPathStr = RemoveEnding(unzippedPathStr,":") unzipFile/O/Z archivePathStr, unzippedPathStr return V_flag #endif String cmd if(stringmatch(StringByKey("OS", igorinfo(3))[0,2],"Win")) // Windows Variable WinVersion = str2num(StringByKey("OSVERSION", igorinfo(3))) if (WinVersion<6.2) // 6.2 = windows 8.0 Print "unzipArchive requires Windows 8 or later" return 0 endif archivePathStr = ParseFilePath(5, archivePathStr, "\\", 0, 0) unzippedPathStr = ParseFilePath(5, unzippedPathStr, "\\", 0, 0) cmd = "powershell.exe -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compression.FileSystem';" sprintf cmd "%s [IO.Compression.ZipFile]::ExtractToDirectory('%s', '%s'); }\"", cmd, archivePathStr, unzippedPathStr else // Mac archivePathStr = ParseFilePath(5, archivePathStr, "/", 0, 0) unzippedPathStr = ParseFilePath(5, unzippedPathStr, "/", 0, 0) sprintf cmd, "unzip %s -d %s", archivePathStr, unzippedPathStr sprintf cmd, "do shell script \"%s\"", cmd endif ExecuteScriptText /B/UNQ/Z cmd if (kVerbose) Print S_value // output from ExecuteScriptText endif return V_flag End

Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More
I recommend that you create a new directory within the temp directory and unzip into that directory. Otherwise, if there happen to be any .ibw files in tempFolder those will be loaded as well.
If you made this change, you could then use LoadData instead of LoadWave to load the entire contents of that temporary directory at once. Though for your purposes, that might complicate things because you need to post-process the data one wave at a time.
January 22, 2021 at 07:06 am - Permalink
Thank you for the suggestion. Yes, I thought about that, but the reason I decided against working in a separate folder was the following: I was under the impression that deleting a folder is kind of a big deal (judging from the warning message in the help), and I can't imagine that there are ibw files in the system's temporary folder. I went for the (seemingly) safer and slightly less robust method here. If you say that I should not worry too much then I might give it a go.
Edit: I tried to get the unzip to work inside a folder, and was thinking about supporting a folder structure inside zip files, but there were quite a few roadblocks. First, deleting a folder really is a big deal with forced user interaction. To keep this process smooth one would need to leave the folder in place, but then what to do with the contents? Is there some way to delete disk folders silently?
Also, while LoadData would make recursive loading easy, I really need to post-process each wave. The main reason is that the data from the measurement software contains the exact same internal wave name in every file, so I cannot load multiple files without renaming each wave before the next file comes in. If LoadData had some way to rename each wave according to the file name, it would work for my case. But I understand the general purpose of LoadData, and the problematic implications of such a behavior (what to do with packet experiments etc.).
So in conclusion, I don't see a way to improve the functionality here without lots of compromises. If there are some neat tricks I would be happy to learn about them.
January 22, 2021 at 07:45 pm - Permalink
> Is there some way to delete disk folders silently?
If you only need for yourself you should be able to tweak that in the settings.
The documentation has
> The default behavior is to display a dialog asking for permission. The user can alter this behavior via the Miscellaneous Settings > dialog's Misc category.
January 24, 2021 at 07:50 am - Permalink
You can use this function to delete a folder and its contents without prompting the user or enabling that setting in the Miscellaneous Settings category:
Note: On macOS (10.14 and later at least), the user will be prompted to allow Igor to use AppleScript the first time this is run.
January 24, 2021 at 11:41 am - Permalink
Thank you very much for the script. Very interesting, also as an example how to run things on a system level. A bit overkill for just extracting a few zip files, though. So for my purposes I will stay with my 'dumb' approach.
January 24, 2021 at 07:11 pm - Permalink