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