tagging release
[dasher.git] / trunk / Src / DasherCore / UserLog.h
blob58b4bb8261822503dc554db9dd5905a34e82d4e3
2 // Handles logging of user activities such as what they write, how
3 // long they were writing, mouse positions, parameters, etc
4 //
5 // Two different kinds of logging can be produced:
6 // 1) Running stats file that records basic stats about
7 // how much and how fast a user is writing.
8 // 2) Detailed per session log file for use during
9 // user trials.
11 // If detailed mode isn't enabled, calls should stop here in this object
12 // and not go on to create UserLogTrial objects or anything that isn't
13 // strictly needed to do the simple logging.
15 // For normal dasher, a new trial involves this sequence:
16 // 1) Program start or new doc
17 // 2) Nav start
18 // 3) Nav stop
19 // 4) Optionally goto 2
20 // A new trial must be indicated by the user resetting using new doc event.
21 // Time from 2-4 is elapsed trial time.
23 // Copyright 2005 by Keith Vertanen
25 #ifndef __USER_LOG_H__
26 #define __USER_LOG_H__
28 #include "FileLogger.h"
29 #include <string>
30 #include <vector>
31 #include "SimpleTimer.h"
32 #include "TimeSpan.h"
33 #include "UserLogTrial.h"
34 #include "Alphabet/Alphabet.h"
35 #include <algorithm>
36 #include "UserLogParam.h"
37 #include "UserLogBase.h"
38 #include "Event.h"
39 #include "XMLUtil.h"
41 using namespace std;
43 extern CFileLogger* g_pLogger;
45 const int USER_LOG_DEFAULT_SIZE_TRIAL_XML = 65536; // How big we think the XML string representing a single trial will be
46 const int LOG_MOUSE_EVERY_MS = 200; // How often to log the mouse position (-1 for never), the frequency is also depends on how often the WM_TIMER event fires in dasher
48 static const string USER_LOG_SIMPLE_FILENAME = "dasher_usage.log"; // Filename of the short text log file
49 static const string USER_LOG_DETAILED_PREFIX = "dasher_"; // Prefix of the detailed XML log files
50 static const bool USER_LOG_DUMP_AFTER_TRIAL = true; // Do we want to dump the XML after each trial is complete?
51 static const string USER_LOG_CURRENT_TRIAL_FILENAME = "CurrentTrial.xml"; // Filename we look for information on what the subject is doing
53 enum eUserLogLevel
55 userLogSimple = 1, // Simple running log file
56 userLogDetailed = 2 // Detailed per session user trial style
59 #ifndef VECTOR_STRING
60 typedef vector<string> VECTOR_STRING;
61 #endif
62 #ifndef VECTOR_STRING_ITER
63 typedef vector<string>::iterator VECTOR_STRING_ITER;
64 #endif
65 #ifndef VECTOR_VECTOR_STRING
66 typedef vector<VECTOR_STRING> VECTOR_VECTOR_STRING;
67 #endif
68 #ifndef VECTOR_VECTOR_STRING_ITER
69 typedef vector<VECTOR_STRING>::iterator VECTOR_VECTOR_STRING_ITER;
70 #endif
72 /// \ingroup Logging
73 /// @{
75 // We need to be notified when parameters we are logging get changed, so we'll
76 // subclass CDasherComponent and implement the HandleEvent() method.
77 class CUserLog : public CUserLogBase
79 public:
80 CUserLog(Dasher::CEventHandler *pEventHandler, CSettingsStore *pSettingsStore, int iLogTypeMask, Dasher::CAlphabet* pAlphabet = NULL);
82 ~CUserLog();
84 // Methods called whenever our user interface gets a relevant event, this
85 // object will decide how to put it into its representation.
86 void AddParam(const string& strName, const string& strValue, int iOptionMask = 0);
87 void AddParam(const string& strName, double dValue, int iOptionMask = 0);
88 void AddParam(const string& strName, int iValue, int iOptionMask = 0);
89 void StartWriting();
90 void StopWriting(float dNats);
91 void StopWriting();
92 void AddSymbols(Dasher::VECTOR_SYMBOL_PROB* pVectorNewSymbolProbs, eUserLogEventType iEvent = userLogEventMouse);
93 void DeleteSymbols(int iNumToDelete, eUserLogEventType iEvent = userLogEventMouse);
94 void NewTrial();
96 void AddWindowSize(int iTop, int iLeft, int iBottom, int iRight);
97 void AddCanvasSize(int iTop, int iLeft, int iBottom, int iRight);
98 void AddMouseLocation(int iX, int iY, float dNats);
99 void AddMouseLocationNormalized(int iX, int iY, bool bStoreIntegerRep, float dNats);
100 void OutputFile();
101 void SetAlphabetPtr(Dasher::CAlphabet* pAlphabet);
102 void InitIsDone();
103 void SetOuputFilename(const string& strFilename = "");
104 int GetLogLevelMask();
105 void KeyDown(int iId, int iType, int iEffect);
106 void HandleEvent(Dasher::CEvent* pEvent);
108 // Methods used by utility that can post-process the log files:
109 CUserLog(string strXMLFilename);
110 VECTOR_VECTOR_STRING GetTabMouseXY(bool bReturnNormalized);
111 VECTOR_VECTOR_DENSITY_GRIDS GetMouseDensity(int iGridSize);
113 protected:
114 CTimeSpan* m_pApplicationSpan; // How long the application has been up
115 string m_strFilename; // Name we output our XML file to
116 VECTOR_USER_LOG_TRIAL_PTR m_vpTrials; // Holds object for each trial in this session
117 VECTOR_USER_LOG_PARAM_PTR m_vParams; // Stores general parameters we want in the XML
118 double m_dLastMouseUpdate; // When the last mouse update was pushed
119 bool m_bSimple; // Are we outputting the simple running log file?
120 bool m_bDetailed; // Are we outputting per session detailed logs?
121 CFileLogger* m_pSimpleLogger; // Used to log the simple running log file
122 Dasher::CAlphabet* m_pAlphabet; // Pointer to Dasher alphabet object
123 bool m_bIsWriting; // Has StartWriting() been called but not StopWriting()?
124 bool m_bInitIsDone; // Set to true once the initialization of default values is done
125 WindowSize m_sCanvasCoordinates; // The size of our canvas from the last call to AddCanvasSize()
126 WindowSize m_sWindowCoordinates; // Records the window coordinates at the start of navigation
127 bool m_bNeedToWriteCanvas; // Do we need to write new canvas coordinates on the next navigation?
128 int m_iLevelMask; // What log level mask we were created with.
129 string m_strCurrentTrialFilename; // Where info about the current subject's trial is stored
131 // Used whenever we need a temporary char* buffer
132 static const int TEMP_BUFFER_SIZE = 4096;
133 char m_szTempBuffer[TEMP_BUFFER_SIZE];
135 CUserLogTrial* AddTrial();
136 CUserLogTrial* GetCurrentTrial();
137 string GetXML();
138 bool WriteXML();
139 bool UpdateMouseLocation();
140 string GetParamsXML();
141 void PrepareNewTrial();
142 string GetCycleParamStats();
143 string GetVersionInfo();
144 void InitMemberVars();
145 void AddInitialParam();
146 void UpdateParam(int iParameter, int iOptionMask);
148 // Things that support simple stats of a single Start/Stop cycle:
149 Dasher::VECTOR_SYMBOL_PROB m_vCycleHistory; // Tracks just the most recent Start/Stop cycle, used for simple logging
150 unsigned int m_iCycleNumDeletes; // Track number of deletes in last Start/Stop cycle
151 CSimpleTimer* m_pCycleTimer; // Length of the last Start/Stop cycle
152 double m_dCycleMouseNormXSum; // Sum of all normalized mouse X coordinates
153 double m_dCycleMouseNormYSum; // Sum of all normalized mouse Y coordinates
154 unsigned long m_iCycleMouseCount; // How many mouse updates have been stores
155 double m_dCycleNats; // The last nats value we got from a mouse event
157 string GetStartStopCycleStats();
158 double GetCycleBits();
159 void ComputeSimpleMousePos(int iX, int iY);
160 void ResetCycle();
161 void InitUsingMask(int iLogLevelMask);
164 /// @}
166 #endif