1 // Command line application that can read a UserLog XML file
2 // and rebuilds the C++ objects that represented it.
4 // Copyright 2005 by Keith Vertanen
7 #include "../../Common/Common.h"
12 #include "../../DasherCore/DasherTypes.h"
14 // Declare our global file logging object
15 #include "FileLogger.h"
17 const eLogLevel gLogLevel
= logDEBUG
;
18 const int gLogOptions
= logTimeStamp
| logDateStamp
| logDeleteOldFile
;
20 const eLogLevel gLogLevel
= logNORMAL
;
21 const int gLogOptions
= logTimeStamp
| logDateStamp
;
23 CFileLogger
* gLogger
= NULL
;
27 #include "../../DasherCore/UserLog.h"
29 // Can't add Utils.h back to CVS so I'm relative linking to another fricken directory
30 #include "../UserLogLoadTest/Utils.h"
33 // In order to track leaks to line number, we need this at the top of every file
34 #include "MemoryLeak.h"
38 static char THIS_FILE
[] = __FILE__
;
44 #ifndef VECTOR_VECTOR_VECTOR_STRING
45 typedef vector
<VECTOR_VECTOR_STRING
> VECTOR_VECTOR_VECTOR_STRING
;
47 #ifndef VECTOR_VECTOR_VECTOR_STRING_ITER
48 typedef vector
<VECTOR_VECTOR_STRING
>::iterator VECTOR_VECTOR_VECTOR_STRING_ITER
;
51 string
GetOutputName(const string
& strBase
, int numFile
, int numTrial
, int numNav
);
52 void OutputToFile(const string
& strData
, const string
& strBase
, int numFile
, int numTrial
, int numNav
);
53 void OutputToFile(DENSITY_GRID data
, int gridSize
, const string
& strBase
, int numFile
, int numTrial
, int numNav
);
54 void OutputData(const string
& strBase
, VECTOR_VECTOR_VECTOR_STRING
* vectorData
, int numFile
, int numTrial
, int numNav
);
56 // Create the output filename based on the current counts
57 string
GetOutputName(const string
& strBase
, int numFile
, int numTrial
, int numNav
)
59 string strResult
= strBase
;
64 sprintf(strNum
, "_file%d", numFile
);
69 sprintf(strNum
, "_trial%d", numTrial
);
74 sprintf(strNum
, "_nav%d", numNav
);
81 void OutputToFile(const string
& strData
, const string
& strBase
, int numFile
, int numTrial
, int numNav
)
83 string strFilename
= GetOutputName(strBase
, numFile
, numTrial
, numNav
);
86 fp
= fopen(strFilename
.c_str(), "w");
90 fputs(strData
.c_str(), fp
);
96 // Output a two dimensional grid of floating point values.
97 // Free up the memory as well.
98 void OutputToFile(DENSITY_GRID data
, int gridSize
, const string
& strBase
, int numFile
, int numTrial
, int numNav
)
103 string strFilename
= GetOutputName(strBase
, numFile
, numTrial
, numNav
);
106 fp
= fopen(strFilename
.c_str(), "w");
112 for (int i
= 0; i
< gridSize
; i
++)
116 for (int j
= 0; j
< gridSize
; j
++)
118 sprintf(strNum
, "%0.4f", data
[i
][j
]);
120 if (j
< (gridSize
- 1))
125 fputs(strLine
.c_str(), fp
);
134 for (int i
= 0; i
< gridSize
; i
++)
148 // Output the passed in string data that is in a vector vector vector.
149 // Outer vector is for the data beloning to each file.
150 // Middle vector has data for each trial in a file.
151 // Inner vector is data for each navigation cycle in a trial.
152 void OutputData(const string
& strBase
, VECTOR_VECTOR_VECTOR_STRING
* vectorData
, int numFile
, int numTrial
, int numNav
)
154 if (vectorData
== NULL
)
157 string strOutput
= "";
159 // Loop over each file
160 for (VECTOR_VECTOR_VECTOR_STRING_ITER iter
= vectorData
->begin();
161 iter
< vectorData
->end();
164 // Loop over each trial
165 for (VECTOR_VECTOR_STRING_ITER iter2
= iter
->begin();
169 // Loop over each navigation cycle
170 for (VECTOR_STRING_ITER iter3
= iter2
->begin();
171 iter3
< iter2
->end();
174 strOutput
+= (*iter3
);
176 // Output if we are suppose to separate each navigation cycle
177 if ((numNav
>= 0) && (strOutput
.length() > 0))
179 OutputToFile(strOutput
, strBase
, numFile
, numTrial
, numNav
);
184 } // end for each nav cycle
186 // Output to the trial file
189 if (strOutput
.length() > 0)
191 OutputToFile(strOutput
, strBase
, numFile
, numTrial
, numNav
);
199 } // end for each trial
201 // Output to for a file
204 if (strOutput
.length() > 0)
206 OutputToFile(strOutput
, strBase
, numFile
, numTrial
, numNav
);
217 } // end for each file
219 // See if we need to output everything to one big file
220 if (strOutput
.length() > 0)
222 OutputToFile(strOutput
, strBase
, numFile
, numTrial
, numNav
);
227 // Output the passed in density grid data that is in a vector vector vector.
228 // Outer vector is for the data beloning to each file.
229 // Middle vector has data for each trial in a file.
230 // Inner vector is data for each navigation cycle in a trial.
231 void OutputData(const string
& strBase
, VECTOR_VECTOR_VECTOR_DENSITY_GRIDS
* vectorData
, int gridSize
, int numFile
, int numTrial
, int numNav
)
233 if (vectorData
== NULL
)
236 DENSITY_GRID output
= NULL
;
238 // Loop over each file
239 for (VECTOR_VECTOR_VECTOR_DENSITY_GRIDS_ITER iter
= vectorData
->begin();
240 iter
< vectorData
->end();
243 // Loop over each trial
244 for (VECTOR_VECTOR_DENSITY_GRIDS_ITER iter2
= iter
->begin();
248 // Loop over each navigation cycle
249 for (VECTOR_DENSITY_GRIDS_ITER iter3
= iter2
->begin();
250 iter3
< iter2
->end();
253 DENSITY_GRID grid
= *iter3
;
254 output
= CUserLogTrial::MergeGrids(gridSize
, output
, grid
);
256 // Output if we are suppose to separate each navigation cycle
257 if ((numNav
>= 0) && (output
!= NULL
))
259 OutputToFile(output
, gridSize
, strBase
, numFile
, numTrial
, numNav
);
264 } // end for each nav cycle
266 // Output to the trial file
270 OutputToFile(output
, gridSize
, strBase
, numFile
, numTrial
, numNav
);
277 } // end for each trial
279 // Output to for a file
283 OutputToFile(output
, gridSize
, strBase
, numFile
, numTrial
, numNav
);
292 } // end for each file
294 // See if we need to output everything to one big file
296 OutputToFile(output
, gridSize
, strBase
, numFile
, numTrial
, numNav
);
300 int main(int argc
, char* argv
[])
304 // Windows debug build memory leak detection
305 EnableLeakDetection();
309 // Global logging object we can use from anywhere
310 gLogger
= new CFileLogger("UserLog.log",
314 { // memory leak scoping
316 string strInListFilename
= "";
317 string strOutputBase
= "out";
318 bool bNormMouse
= false;
319 bool bDensityMouse
= false;
322 // These track the number index we use on output files.
323 // -1 if we aren't separating on this item
324 int numOutputFile
= -1;
325 int numOutputTrial
= -1;
326 int numOutputNav
= -1;
330 cout
<< "UserLog" << endl
;
331 cout
<< " -in <XML log filename>" << endl
;
332 cout
<< " -inList <file with list of log filenames>" << endl
;
333 cout
<< " -out <output base name>" << endl
;
334 cout
<< " -separateFiles" << endl
;
335 cout
<< " -separateTrials" << endl
;
336 cout
<< " -separateNavs" << endl
;
337 cout
<< " -normMouse" << endl
;
338 cout
<< " -densityMouse" << endl
;
339 cout
<< " -densityGrid <grid size>" << endl
;
345 VECTOR_STRING vectorInputFiles
;
347 // Parse the command line options
351 string strParam
= makeLower(argv
[i
]);
352 string strNextParam
= "";
355 strNextParam
= argv
[i
+1];
357 if (strParam
.compare("-in") == 0)
359 vectorInputFiles
.push_back(strNextParam
);
362 else if (strParam
.compare("-inlist") == 0)
364 strInListFilename
= strNextParam
;
367 else if (strParam
.compare("-out") == 0)
369 strOutputBase
= strNextParam
;
372 else if (strParam
.compare("-separatefiles") == 0)
376 else if (strParam
.compare("-separatetrials") == 0)
380 else if (strParam
.compare("-separatenavs") == 0)
384 else if (strParam
.compare("-normmouse") == 0)
388 else if (strParam
.compare("-densitymouse") == 0)
390 bDensityMouse
= true;
392 else if (strParam
.compare("-densitygrid") == 0)
394 gridSize
= atoi(strNextParam
.c_str());
399 // Failure to parse this parameter
400 cout
<< "Unknown switch: " << strParam
<< endl
;
406 // Read in the list of files we are suppose to process
407 if (strInListFilename
.length() > 0)
410 fp
= fopen(strInListFilename
.c_str(), "r");
417 fscanf(fp
, "%s\n", buffer
);
419 if (strlen(buffer
) > 0)
420 vectorInputFiles
.push_back(buffer
);
427 cout
<< "Failed to open test list file: " << strInListFilename
.c_str() << endl
;
430 // Process each of our input files
431 VECTOR_VECTOR_VECTOR_STRING vectorStrResult
;
432 VECTOR_VECTOR_VECTOR_DENSITY_GRIDS vectorGridResult
;
434 for (VECTOR_STRING_ITER iter
= vectorInputFiles
.begin(); iter
< vectorInputFiles
.end(); iter
++)
436 string strFile
= (string
) *iter
;
438 CUserLog
objUserLog(strFile
);
442 VECTOR_VECTOR_STRING vectorMouse
= objUserLog
.GetTabMouseXY(true);
443 vectorStrResult
.push_back(vectorMouse
);
444 } else if (bDensityMouse
)
446 VECTOR_VECTOR_DENSITY_GRIDS vectorGrid
= objUserLog
.GetMouseDensity(gridSize
);
447 vectorGridResult
.push_back(vectorGrid
);
451 if (vectorStrResult
.size() > 0)
452 OutputData(strOutputBase
, &vectorStrResult
, numOutputFile
, numOutputTrial
, numOutputNav
);
453 else if (vectorGridResult
.size() > 0)
454 OutputData(strOutputBase
, &vectorGridResult
, gridSize
, numOutputFile
, numOutputTrial
, numOutputNav
);