Using filename to name waves.
rhjpires
I am trying to create a simple script that would automatically load and rename my waves as I import them from files within a data folder. Each file contains columns each referring to different measurements of a given sample. They are therefore related by the sample, which is indicated in the filename. File names are quite structured, for example: 25C_Cell1_1, 25C_Cell1_2 up to 25_Cell1_35 (for example).
Each file contains different columns containing different properties that were measured, Time, Property1, Property2, etc
I now would like for Igor to load them, and rename them by calling the filename and adding a letter that would specify which property that wave refers too. For example, instead of loading and calling the waves wave0, wave1, wave2, etc. It should call it T_Filename, P1_Filename, P2_Filename. The original data is enough organized that I can say that Wave0 will correspond to time, wave1 to property 1, wave2 to property 2, etc.
Can I do this immediately on the /A= flag of Loadwave? Below you find my miserable attempt to do this. Here you see WaveX as the file, but the result is not just the filename, but the whole path.
Please let me know your thoughts.
Kind regards,
Ricardo
PS: Some print commands are just there to guide me to what the script is doing.
#pragma rtGlobals=3 // Use modern global access method and strict wave access.
Menu "Macros"
"Load and Rename TXT Data", LoadAndRename()
Menu "Macros"
"Load and Rename TXT Data", LoadAndRename()
Function/S LoadAndRename()
variable RefNum
String message = "Select one or more files"
String InFile
String fileFilters = "Data Files (*.txt,*.dat,*.csv):.txt,.dat,.csv;"
fileFilters += "All Files:.*;"
Open /D /R /MULT=1 /F=fileFilters /M=message RefNum
InFile = S_fileName
Print "The RefNUM is: ", refNum
Print "The Selected Files are: ", InFile
if (strlen(InFile) == 0)
Print "File Contains No Data - Script was Cancelled!!"
else
Variable numFilesSelected = ItemsInList(InFile, "\r")
Variable i
for(i=0; i String WaveX = StringFromList(i, InFile, "\r")
Printf "%d: %s\r", i, WaveX
// Add commands here to load the actual waves.
LoadWave/A/D/G/W/K=2 WaveX // The Flag "/G" indicates that the data is GENERAL TEXT
String ForceWave = "T_"+WaveX
String baseName = CleanupName(InFile,0)
Print "THIS IS THE BASENAME: ", baseName
Print "this is ForceWave ", ForceWave
Print "numFilesSelected ******* ", numFilesSelected
endfor
endif
Killwaves/A/Z/F
Print "*********************** END OF SCRIPT ********************************"
return InFile // Will be empty if user canceled
END
ParseFilePath
to obtain various parts of a file path.For example, to get the wave name without the extension from the full path using your string variable:
ParseFilePath(3, WaveX, ":", 0, 0)
October 6, 2015 at 05:25 am - Permalink
October 6, 2015 at 07:59 am - Permalink
Within the File, not all columns/waves are relevant. So I decided to let Igor autoname them (wave0, wave1, ...), Kill unnecessary waves, duplicate the relevant ones with the required name, and then kill all autonamed waves before proceeding to the next file.
variable RefNum
String message = "Select one or more files"
String InFile
String fileFilters = "Data Files (*.txt,*.dat,*.csv):.txt,.dat,.csv;"
fileFilters += "All Files:.*;"
Open /D /R /MULT=1 /F=fileFilters /M=message RefNum
InFile = S_fileName
Print "The RefNUM is: ", refNum
Print "The Selected Files are: ", InFile
if (strlen(InFile) == 0)
Print "File Contains No Data - Script was Cancelled!!"
else
Variable numFilesSelected = ItemsInList(InFile, "\r")
Variable i
for(i=0; i<numFilesSelected; i+=1)
String WaveX = StringFromList(i, InFile, "\r")
Printf "%d: %s\r", i, WaveX
String FileName = ParseFilePath(3, WaveX, ":", 0, 0)
// Add commands here to load the actual waves.
LoadWave/A/D/G/W/K=2 WaveX // The Flag "/G" indicates that the data is GENERAL TEXT
Wave Wave0, Wave1, Wave2, Wave3, Wave4
Killwaves Wave0, Wave1, Wave2, Wave3, Wave4 //First 5 Waves are unimportant
Wave Wave5, Wave6, Wave7, wave8, Wave9
Duplicate/O Wave5 $("F_"+FileName+"_Ext")/WAVE=ForceWave_Extend
Duplicate/O Wave6 $("T_"+FileName+"_Ext")/WAVE=TimeWave_Extend
Duplicate/O Wave7 $("Sep_"+FileName+"_Ext")/WAVE=SepWave_Extend
Killwaves Wave5, Wave6, Wave7, Wave8, Wave9 //Clean up
Wave Wave10, Wave11, Wave12, Wave13, Wave14
Duplicate/O Wave11 $("F_"+FileName+"_Pause")/WAVE=ForceWave_Pause
Duplicate/O Wave12 $("T_"+FileName+"_Pause")/WAVE=TimeWave_Pause
Duplicate/O Wave13 $("Sep_"+FileName+"_Pause")/WAVE=SepWave_Pause
Killwaves Wave10, Wave11, Wave12, Wave13, Wave14 //Clean up
endfor
endif
Print "*********************** END OF SCRIPT ********************************"
return InFile // Will be empty if user canceled
END
There must be a more streamlined way to do this. Can I for example use LoadWave to tell Igor to pick only specific blocks of Data?
Although data is delimited by a space, I have been importing data as General Text because so far this has worked out better than using delimited text as import mode.
I place below an example of what the original TXT Files look like. Each contains 15 datasets separaded by a space, and a bunch of annotations. Is there a way to specifically collect selected columns of data from such a file?
Thanks for the suggestions!!
# TEXT
# TEXT
# TEXT
# TEXT
# MORE TEXT
# MORE TEXT
# MORE TEXT
-3.365417E-10 0.0017089844 8.612418E-6 5.9999998E-6 -2.5E-5
-3.3551864E-10 0.005126953 8.610098E-6 5.9999998E-6 -2.5E-5
-3.3567965E-10 0.008544922 8.607764E-6 5.9999998E-6 -2.5E-5
-3.3599612E-10 0.011962891 8.605427E-6 5.9999998E-6 -2.5E-5
# TEXT
# TEXT
# TEXT
# TEXT
# MORE TEXT
# MORE TEXT
# MORE TEXT
-3.365417E-10 0.0017089844 8.612418E-6 5.9999998E-6 -2.5E-5
-3.3551864E-10 0.005126953 8.610098E-6 5.9999998E-6 -2.5E-5
-3.3567965E-10 0.008544922 8.607764E-6 5.9999998E-6 -2.5E-5
-3.3599612E-10 0.011962891 8.605427E-6 5.9999998E-6 -2.5E-5
# TEXT
# TEXT
# TEXT
# TEXT
# MORE TEXT
# MORE TEXT
# MORE TEXT
-3.365417E-10 0.0017089844 8.612418E-6 5.9999998E-6 -2.5E-5
-3.3551864E-10 0.005126953 8.610098E-6 5.9999998E-6 -2.5E-5
-3.3567965E-10 0.008544922 8.607764E-6 5.9999998E-6 -2.5E-5
-3.3599612E-10 0.011962891 8.605427E-6 5.9999998E-6 -2.5E-5
October 6, 2015 at 09:40 am - Permalink
If may not be of interest to you but ...
You can tell LoadWave to skip loading a column by specifying its name as '_skip_' using the /B flag.
October 6, 2015 at 09:37 am - Permalink
Also, rather than skipping columns I was wondering if it would be possible to immediately tell which column number to extract the wave. I understand I could also use Rename rather than duplicate, but I still have to extract unnecessary waves and then kill them. Or do I?
Many thanks,
R.
October 6, 2015 at 10:10 am - Permalink
You can construct the /B parameter using strings calculated based on the file name that you determine from S_fileName. For example:
String fileName = ParseFilePath(3, filePath, ":", 0, 0) // Get file name, without extension, from path
String singleQuote = "'"
String semicolon = ";"
String columnInfoStr = ""
columnInfoStr += "N=" + singleQuote + fileName + "_Time" + singleQuote + semicolon
columnInfoStr += "N=" + singleQuote + fileName + "_Property1" + singleQuote + semicolon
columnInfoStr += "N=" + singleQuote + fileName + "_Property2" + singleQuote + semicolon
columnInfoStr += "N='_skip_';" // Skip Property3 as we don't care about it
columnInfoStr += "N=" + singleQuote + fileName + "_Property4" + singleQuote + semicolon
LoadWave/A/O/D/G/K=2/B=columnInfoStr filePath
I don't understand this.
You can load a range of columns, rather than all columns, using the /L flag.
Using Rename after LoadWave is problematic because if a wave already exists with the name you want to use, you Rename will fail. This is one of the benefits of /B - it can override waves with existing names, if you include the /O flag.
If you can't use /B for some reason then I would use Duplicate/O followed by KillWaves. This effectively accomplishes a rename without the problem explained in the preceding paragraph.
October 6, 2015 at 11:05 am - Permalink
October 7, 2015 at 12:10 am - Permalink