1 #pragma rtGlobals=1 // Use modern global access method.
2 #pragma IgorVersion = 4.0
6 // ExportMFP1D.ipf - A procedure to export force curves from MFP1D to 'hooke'
8 // Copyright (c) 2009 Rolf Schmidt, Montreal
9 // rschmidt@alcor.concordia.ca
11 // This procedure is released under the GNU General Public License version 2
16 // the wave note is now correctly and fully exported in Igor 4
18 // split functionality into ExportMFP1DFolder and ExportMFP1DWaves
19 // ExportMFP1DFolder: export individual Igor binary waves file from a folder
20 // ExportMFP1DWaves: export all currently open waves to a folder
22 // added the IgorVersion pragma
24 // changed the filename finding algorithm to work with Igor 4 and up
25 // Igor 5 users can use the code marked 'the following only works in Igor 5 and up' instead
26 // the procedure now catches 'Cancel' on NewPath
27 // added version information
29 // changed the procedure so that it runs in Igor as well as in MFP (ie Igor with MFP plug-in)
31 // How to use ExportMFP1D()
32 // - save all current waves of interest (ExportMFP1D() kills all open waves before exporting files)
33 // - execute ExportMFP1D() from the command line
34 // - browse to a folder containing force curves (a 'force curve' consists of two files: one 'deflection' and one 'LVDT' file
35 // - ExportMFP1D() will now iterate through all the waves in the folder, extract the header information and create four columns:
36 // 1: approach (x) 2: approach (y) 3: retraction (x) 4; retraction (y)
37 // - the resulting files are saved in the same folder and the same base name as the original files (ie without 'deflection' and 'LVDT')
38 // CAUTION: existing files will be overwritten!
39 // - these files can then be analyzed with 'hooke'
41 Function ExportMFP1DFolder()
46 // set the path (used for opening the waves and saving the output files later)
47 NewPath /O /Q /M="Choose the folder that contains the waves" PathExport1D
52 // get a list of all Igor binary waves in the folder
53 sList=IndexedFile(PathExport1D,-1,".ibw")
55 for(iCount=0; iCount<ItemsInList(sList); iCount+=1)
56 LoadWave /P=PathExport1D /Q StringFromList(iCount, sList)
60 // kill the export path
61 KillPath /Z PathExport1D
64 Function ExportMFP1DWaves()
72 String sWaveDeflection
83 // set the path (used for saving the output files later)
84 NewPath /O /Q /M="Choose the folder to save the waves" PathExport1D
86 // get a list of all LVDT waves (could be deflection as well, they always come in a pair)
87 sList=WaveList("*LVDT*", ";", "")
89 // iterate through all the LVDT waves
90 for(iCount=0; iCount<ItemsInList(sList); iCount+=1)
91 // create the wave names as string
92 // the following only works in Igor 5 and up
93 // sWaveLVDT=ReplaceString(".ibw",StringFromList(iCount, sList), "")
94 // sWaveDeflection=ReplaceString("LVDT",sWaveLVDT, "deflection")
95 // sWaveCombined=ReplaceString("LVDT",sWaveLVDT, "_")
96 // END: the following only works in Igor 5 and up
98 // the following works in Igor 4 and up
99 // treat the filename as a key-value list with '.' as a separator
100 // use the first entry (ie 0) as the filename without extension
101 sWaveLVDT=StringFromList(0, StringFromList(iCount, sList), ".")
103 // treat the filename as a key-value list with 'LVDT' as a separator
104 // use the first entry (ie 0) as the first part of the filename
105 sFileName1=StringFromList(0, sWaveLVDT, "LVDT")
106 // getting the second part of the filename is a bit trickier
107 // first, we 'remove' the first part of the filename by treating it as a key
108 // using 'LVDT' as a separator
109 sFileName2=StringByKey(sFileName1, sWaveLVDT, "LVDT")
110 // unfortunately, StringByKey only removes the first character of the separator
111 // to get the second part of the filename, we use VD as the key and 'T' as the separator
112 sFileName2=StringByKey("VD", sFileName2, "T")
113 // then we create the wave names as follows:
114 sWaveDeflection=sFileName1+"deflection"+sFileName2
116 sWaveCombined=sFileName1+"_"+sFileName2
118 // END: the following works in Igor 4 and up
120 // create the waves we need
121 Wave wLVDT=$sWaveLVDT
122 Wave wDeflection=$sWaveDeflection
124 // open the output text file, add extension
125 Open /P=PathExport1D iRefNum as sWaveCombined+".txt"
128 fprintf iRefNum, "Wave:"+sWaveCombined+"\r"
129 fprintf iRefNum, "WaveLVDT:"+sWaveLVDT+"\r"
130 fprintf iRefNum, "WaveDeflection:"+sWaveDeflection+"\r"
132 // the number of points (use WaveStats to get them) are identical for LVDT and Deflection
135 fprintf iRefNum, "Rows:"+num2str(iPoints)+"\r"
137 // add the note to the file
138 // the notes are identical for LVDT and Deflection
139 // the following only works in Igor 5 and up
140 // fprintf iRefNum, note(wDeflection)
141 // END: the following only works in Igor 5 and up
143 // in order to get the correct number of lines in the note, we have to specify the EOF as \r\n
144 for(iLine=0; iLine<ItemsInList(sNote, "\r\n");iLine+=1)
145 // print every line to the output file
146 fprintf iRefNum, StringFromList(iLine, sNote, "\r\n")
147 // add a CR/LF for every but the last line
148 if(iLine<ItemsInList(sNote, "\r\n")-1)
149 fprintf iRefNum, "\r\n"
153 // separate the approach from the retraction
154 // by simply taking the first half of the points to be the approach
155 // and the second half to be the retraction
156 // this probably has to be changed for dual pulls
157 Duplicate /O /R=[0, iPoints] wLVDT, wApproachX
158 Duplicate /O /R=[0, iPoints] wDeflection, wApproachY
159 Duplicate /O /R=[iPoints+1] wLVDT, wRetractionX
160 Duplicate /O /R=[iPoints+1] wDeflection, wRetractionY
162 // create four columns line by line
163 // 1: approach x 2: approach y 3: retraction x 4: retraction y
164 for(iLine=0; iLine<iPoints; iLine+=1)
165 sLine=num2str(wApproachX[iLine])+"\t"+num2str(wApproachY[iLine])
166 sLine=sLine+"\t"+num2str(wRetractionX[iLine])+"\t"+num2str(wRetractionY[iLine])
167 // add the line to the file
168 fprintf iRefNum, "\r"+sLine
171 // save the text file to disk
172 print "Exporting "+sWaveCombined
177 print "Export completed ("+num2str(ItemsInList(sList))+" files)"
179 // kill the temporary waves used
180 // given the names, it is unlikely that this function will interfere with data
181 KillWaves /Z wApproachX
182 KillWaves /Z wApproachY
183 KillWaves /Z wRetractionX
184 KillWaves /Z wRetractionY