public static void toARFF(string aDataDirectory, string masterDirectory, int maxControllers, string sourceFile, int annotators,string[] filter) { int featureVectorIndex = 0; MITesDecoder aMITesDecoder = new MITesDecoder(); MITesLoggerReader aMITesLoggerReader = new MITesLoggerReader(aMITesDecoder, aDataDirectory); SXML.SensorAnnotation sannotation = null; MITesFeatures.core.conf.GeneralConfiguration configuration = null; AXML.Annotation[] aannotation = new AXML.Annotation[annotators]; AXML.Reader[] readers=new AXML.Reader[annotators]; AXML.Annotation intersection = null; AXML.Annotation[] difference = new AXML.Annotation[annotators]; AXML.Annotation realtimeAnnotation = new AXML.Reader(masterDirectory, aDataDirectory).parse(); realtimeAnnotation.RemoveData(filter); for (int i = 0; (i < annotators); i++) { readers[i] = new AXML.Reader(masterDirectory, aDataDirectory, sourceFile + i + ".xml"); aannotation[i] = readers[i].parse(); aannotation[i].RemoveData(filter); aannotation[i].DataDirectory = aDataDirectory; if (intersection == null) intersection = aannotation[i]; else intersection = intersection.Intersect(aannotation[i]); } for (int i = 0; (i < annotators); i++) difference[i] = aannotation[i].Difference(intersection); SXML.Reader sreader = new SXML.Reader(masterDirectory, aDataDirectory); sannotation = sreader.parse(maxControllers); MITesFeatures.core.conf.ConfigurationReader creader = new MITesFeatures.core.conf.ConfigurationReader(aDataDirectory); configuration = creader.parse(); Extractor.Initialize(aMITesDecoder, aDataDirectory, aannotation[0], sannotation,configuration); TextWriter tw = new StreamWriter(aDataDirectory + "\\output-"+sourceFile+".arff"); tw.WriteLine("@RELATION wockets"); tw.WriteLine(Extractor.GetArffHeader()); tw.WriteLine("@ATTRIBUTE INDEX NUMERIC"); tw.WriteLine("@ATTRIBUTE ANNOTATORS_AGREE NUMERIC"); Hashtable recorded_activities = new Hashtable(); for (int k = 0; (k < annotators); k++) { //tw.Write("@ATTRIBUTE annotator"+k+" {unknown"); //tw.Write("@ATTRIBUTE annotator" + k + " {"); for (int i = 0; (i < aannotation[k].Data.Count); i++) { AXML.AnnotatedRecord record = ((AXML.AnnotatedRecord)aannotation[k].Data[i]); string activity = ""; for (int j = 0; (j < record.Labels.Count); j++) { if (j == record.Labels.Count - 1) activity += ((AXML.Label)record.Labels[j]).Name; else activity += ((AXML.Label)record.Labels[j]).Name + "_"; } activity = activity.Replace("none", "").Replace('-', '_').Replace(':', '_').Replace('%', '_').Replace('/', '_'); activity = Regex.Replace(activity, "[_]+", "_"); activity = Regex.Replace(activity, "^[_]+", ""); activity = Regex.Replace(activity, "[_]+$", ""); //only output activity labels that have not been seen if (recorded_activities.Contains(activity) == false) { //tw.Write("," + activity); recorded_activities[activity] = activity; } } } for (int k = 0; (k < annotators); k++) { tw.Write("@ATTRIBUTE annotator" + k + " {unknown,flapping,rocking,flaprock}\n"); //foreach ( DictionaryEntry de in recorded_activities ) // tw.Write("," + (string) de.Key); //tw.WriteLine("}"); } tw.Write("@ATTRIBUTE realtime {unknown,flapping,rocking,flaprock}\n"); //foreach (DictionaryEntry de in recorded_activities) // tw.Write("," + (string)de.Key); //tw.WriteLine("}"); tw.WriteLine("@DATA"); bool isData = aMITesLoggerReader.GetSensorData(10); int channel = 0, x = 0, y = 0, z = 0; double unixtimestamp = 0.0; int[] differenceIndex = new int[annotators]; AXML.AnnotatedRecord[] annotatedRecord = new AXML.AnnotatedRecord[annotators]; int intersectionIndex = 0; string intersection_activity = "unknown"; AXML.AnnotatedRecord intersectionRecord = ((AXML.AnnotatedRecord)intersection.Data[intersectionIndex]); string[] current_activity = new string[annotators]; string realtime_activity = "unknown"; int realtimeIndex = 0; AXML.AnnotatedRecord realtimeRecord = ((AXML.AnnotatedRecord)realtimeAnnotation.Data[realtimeIndex]); for (int i = 0; (i < annotators); i++) { differenceIndex[i] = 0; annotatedRecord[i] = ((AXML.AnnotatedRecord)difference[i].Data[differenceIndex[i]]); current_activity[i] = "unknown"; } do { //decode the frame channel = aMITesDecoder.GetSomeMITesData()[0].channel; x = aMITesDecoder.GetSomeMITesData()[0].x; y = aMITesDecoder.GetSomeMITesData()[0].y; z = aMITesDecoder.GetSomeMITesData()[0].z; unixtimestamp = aMITesDecoder.GetSomeMITesData()[0].unixTimeStamp; double lastTimeStamp = Extractor.StoreMITesWindow(); for (int i = 0; (i < annotators); i++) { if (unixtimestamp > annotatedRecord[i].EndUnix) { current_activity[i] = "unknown"; if (differenceIndex[i] < difference[i].Data.Count - 1) { differenceIndex[i] = differenceIndex[i]+1; annotatedRecord[i] = ((AXML.AnnotatedRecord)difference[i].Data[differenceIndex[i]]); } } } if (unixtimestamp > realtimeRecord.EndUnix) { realtime_activity = "unknown"; realtimeIndex++; if (realtimeIndex < realtimeAnnotation.Data.Count) realtimeRecord = ((AXML.AnnotatedRecord)realtimeAnnotation.Data[realtimeIndex]); } if (unixtimestamp > intersectionRecord.EndUnix) { intersection_activity = "unknown"; if (intersectionIndex < intersection.Data.Count - 1) { intersectionIndex = intersectionIndex + 1; intersectionRecord = ((AXML.AnnotatedRecord)intersection.Data[intersectionIndex]); } } for (int i = 0; (i < annotators); i++) { if ((lastTimeStamp >= annotatedRecord[i].StartUnix) && (lastTimeStamp <= annotatedRecord[i].EndUnix) && current_activity[i].Equals("unknown")) { current_activity[i] = ""; for (int j = 0; (j < annotatedRecord[i].Labels.Count); j++) { if (j == annotatedRecord[i].Labels.Count - 1) current_activity[i] += ((AXML.Label)annotatedRecord[i].Labels[j]).Name; else current_activity[i] += ((AXML.Label)annotatedRecord[i].Labels[j]).Name + "_"; } current_activity[i] = current_activity[i].Replace("none", "").Replace('-', '_').Replace(':', '_').Replace('%', '_').Replace('/', '_'); current_activity[i] = Regex.Replace(current_activity[i], "[_]+", "_"); current_activity[i] = Regex.Replace(current_activity[i], "^[_]+", ""); current_activity[i] = Regex.Replace(current_activity[i], "[_]+$", ""); } else if (lastTimeStamp > annotatedRecord[i].EndUnix) current_activity[i] = "unknown"; } if ((lastTimeStamp >= realtimeRecord.StartUnix) && (lastTimeStamp <= realtimeRecord.EndUnix) && realtime_activity.Equals("unknown")) { realtime_activity = ""; for (int j = 0; (j < realtimeRecord.Labels.Count); j++) { if (j == realtimeRecord.Labels.Count - 1) realtime_activity += ((AXML.Label)realtimeRecord.Labels[j]).Name; else realtime_activity += ((AXML.Label)realtimeRecord.Labels[j]).Name + "_"; } realtime_activity = realtime_activity.Replace("none", "").Replace('-', '_').Replace(':', '_').Replace('%', '_').Replace('/', '_'); realtime_activity = Regex.Replace(realtime_activity, "[_]+", "_"); realtime_activity = Regex.Replace(realtime_activity, "^[_]+", ""); realtime_activity = Regex.Replace(realtime_activity, "[_]+$", ""); } else if (lastTimeStamp > realtimeRecord.EndUnix) realtime_activity = "unknown"; if ((lastTimeStamp >= intersectionRecord.StartUnix) && (lastTimeStamp <= intersectionRecord.EndUnix) && intersection_activity.Equals("unknown")) { intersection_activity = ""; for (int j = 0; (j < intersectionRecord.Labels.Count); j++) { if (j == intersectionRecord.Labels.Count - 1) intersection_activity += ((AXML.Label)intersectionRecord.Labels[j]).Name; else intersection_activity += ((AXML.Label)intersectionRecord.Labels[j]).Name + "_"; } intersection_activity = intersection_activity.Replace("none", "").Replace('-', '_').Replace(':', '_').Replace('%', '_').Replace('/', '_'); intersection_activity = Regex.Replace(intersection_activity, "[_]+", "_"); intersection_activity = Regex.Replace(intersection_activity, "^[_]+", ""); intersection_activity = Regex.Replace(intersection_activity, "[_]+$", ""); } if ((Extractor.GenerateFeatureVector(lastTimeStamp))) { string activity_suffix = "," + featureVectorIndex; if (intersection_activity.Equals("unknown") == true) //disagreement or agreement unknown { if ((current_activity[0] == "unknown") && (current_activity[1] == "unknown")) activity_suffix += ",1"; else activity_suffix += ",0"; for (int i = 0; (i < annotators); i++) activity_suffix += "," + current_activity[i]; } else { activity_suffix += ",1"; for (int i = 0; (i < annotators); i++) activity_suffix += "," + intersection_activity; } string arffSample = Extractor.toString() + activity_suffix; //if (activity_suffix.Contains("unknown") == false) //{ tw.WriteLine(arffSample+","+realtime_activity); featureVectorIndex++; //} } } while (isData = aMITesLoggerReader.GetSensorData(10)); tw.Close(); }
private void MITesSenderThread() { MITesDecoder aMITesDecoder = new MITesDecoder(); MITesLoggerReader aMITesLoggerReader = new MITesLoggerReader(aMITesDecoder, MITES_SAMPLE_DIRECTORY); MITesData data = new MITesData(); double UnixTime = ((TimeSpan)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)))).TotalMilliseconds; //double difference=0; double previousTime=0; Random random = new Random(); int bytePerSecond = 0; int samplesPerSecond=0; DateTime previousDateTime=DateTime.Now; bool workingBT=false; while (true) { //Thread.Sleep(1000); if (BluetoothConnection.IsOpen) { try { if (startTransmission) { bool isData = aMITesLoggerReader.GetSensorData(10); int channel = 0, x = 0, y = 0, z = 0; double unixtimestamp = 0.0; double lasttime = 0.0; byte[] rawSample = aMITesDecoder.GetSomeMITesData()[0].rawBytes; do { //decode the frame if (realistic == false) { //Thread.Sleep(gapmillseconds); if (rawSample[0] == 4) rawSample[0] = 8; else rawSample[0] = 4; rawSample[1] = (byte)random.Next(256); rawSample[2] = (byte)random.Next(256); rawSample[3] = (byte)random.Next(256); //BluetoothConnection.Write(rawSample, 0, 5); samplesPerSecond++; if ((samplesPerSecond % 5)==0) BluetoothConnection.Write(mitesData, 0, 2); else BluetoothConnection.Write(rawSample, 0, 5); workingBT = true; } else if ((int)previousTime != 0) { channel = aMITesDecoder.GetSomeMITesData()[0].channel; x = aMITesDecoder.GetSomeMITesData()[0].x; y = aMITesDecoder.GetSomeMITesData()[0].y; z = aMITesDecoder.GetSomeMITesData()[0].z; unixtimestamp = aMITesDecoder.GetSomeMITesData()[0].unixTimeStamp; Thread.Sleep((int)previousTime); previousTime = unixtimestamp; if (channel != 83) BluetoothConnection.Write(aMITesDecoder.GetSomeMITesData()[0].rawBytes, 0, 5); } double seconds = ((TimeSpan)(DateTime.Now - previousDateTime)).TotalSeconds; if (seconds > 5) { sps = ((int)(samplesPerSecond / 5)).ToString(); bps = ((int)(samplesPerSecond * 5)).ToString(); samplesPerSecond = 0; previousDateTime = DateTime.Now; } } while ((realistic == false));//|| (isData = aMITesLoggerReader.GetSensorData(10))); BluetoothConnection.Close(); Application.Exit(); } else { //2 sync bytes BluetoothConnection.Write(mitesData, 0, 2); //Thread.Sleep(5); } /*else { int startTime = (int)((TimeSpan)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)))).TotalSeconds; do { Thread.Sleep(gapmillseconds); //decode the frame if (data.channel == 4) data.channel = 8; else data.channel = 4; data.x = (short)random.Next(1000); data.y = (short)random.Next(1000); data.z = (short)random.Next(1000); data.unixTimeStamp = ((TimeSpan)(DateTime.UtcNow.Subtract(new DateTime(1970, 1,1)))).TotalMilliseconds; data.ResetRawVals(); if (channel != 83) BluetoothConnection.Write(aMITesDecoder.GetSomeMITesData()[0].rawBytes, 0, 5); int currentTime = (int) ((TimeSpan)(DateTime.UtcNow.Subtract(new DateTime(1970, 1,1)))).TotalSeconds; } while (currentTime<(startTime+totalSeconds)); }*/ } catch (Exception e) { samplesPerSecond = 0; if (workingBT == true) //only reset if BT was already working { BluetoothConnection.Close(); BluetoothConnection = new SerialPort(); this.BluetoothConnection.PortName = INCOMING_PORT; BluetoothConnection.WriteTimeout = 1000; BluetoothConnection.StopBits = StopBits.One; BluetoothConnection.BaudRate = 57600; BluetoothConnection.Parity = Parity.None; //BluetoothConnection. BluetoothConnection.Open(); workingBT = false; } } } } }
public static void toARFF2(string aDataDirectory, string masterDirectory, int maxControllers) { MITesDecoder aMITesDecoder = new MITesDecoder(); MITesLoggerReader aMITesLoggerReader = new MITesLoggerReader(aMITesDecoder, aDataDirectory); AXML.Annotation aannotation = null; SXML.SensorAnnotation sannotation = null; Hashtable calibrations = null; AXML.Reader reader = new AXML.Reader(masterDirectory, aDataDirectory,"AnnotationIntervals.xml"); aannotation = reader.parse(); aannotation.DataDirectory = aDataDirectory; SXML.Reader sreader = new SXML.Reader(masterDirectory, aDataDirectory); sannotation = sreader.parse(maxControllers); SOXML.Reader calreader = new SOXML.Reader(aDataDirectory); calibrations = calreader.parse(); Extractor.Initialize2(aMITesDecoder, aDataDirectory, aannotation, sannotation,calibrations); TextWriter tw = new StreamWriter(aDataDirectory + "\\output2.arff"); tw.WriteLine("@RELATION wockets"); tw.WriteLine(Extractor.GetArffHeader2()); tw.Write("@ATTRIBUTE activity {unknown"); Hashtable recorded_activities = new Hashtable(); for (int i = 0; (i < aannotation.Data.Count); i++) { AXML.AnnotatedRecord record = ((AXML.AnnotatedRecord)aannotation.Data[i]); string activity = ""; for (int j = 0; (j < record.Labels.Count); j++) { if (j == record.Labels.Count - 1) activity += ((AXML.Label)record.Labels[j]).Name; else activity += ((AXML.Label)record.Labels[j]).Name + "_"; } activity = activity.Replace("none", "").Replace('-', '_').Replace(':', '_').Replace('%', '_').Replace('/', '_'); activity = Regex.Replace(activity, "[_]+", "_"); activity = Regex.Replace(activity, "^[_]+", ""); activity = Regex.Replace(activity, "[_]+$", ""); //only output activity labels that have not been seen if (recorded_activities.Contains(activity) == false) { tw.Write("," + activity); recorded_activities[activity] = activity; } } tw.WriteLine("}"); tw.WriteLine("@DATA"); bool isData = aMITesLoggerReader.GetSensorData(10); int channel = 0, x = 0, y = 0, z = 0; double unixtimestamp = 0.0; int activityIndex = 0; AXML.AnnotatedRecord annotatedRecord = ((AXML.AnnotatedRecord)aannotation.Data[activityIndex]); string current_activity = "unknown"; do { //decode the frame channel = aMITesDecoder.GetSomeMITesData()[0].channel; x = aMITesDecoder.GetSomeMITesData()[0].x; y = aMITesDecoder.GetSomeMITesData()[0].y; z = aMITesDecoder.GetSomeMITesData()[0].z; unixtimestamp = aMITesDecoder.GetSomeMITesData()[0].unixTimeStamp; double lastTimeStamp = Extractor.StoreMITesWindow(); //DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, 0); //dt=dt.AddMilliseconds(unixtimestamp); //DateTime dt2 = new DateTime(1970, 1, 1, 0, 0, 0, 0); //dt2 = dt2.AddMilliseconds(annotatedRecord.EndUnix); if (unixtimestamp > annotatedRecord.EndUnix) { current_activity = "unknown"; if (activityIndex < aannotation.Data.Count - 1) { activityIndex++; annotatedRecord = ((AXML.AnnotatedRecord)aannotation.Data[activityIndex]); } } if ((lastTimeStamp >= annotatedRecord.StartUnix) && (lastTimeStamp <= annotatedRecord.EndUnix) && current_activity.Equals("unknown")) { current_activity = ""; for (int j = 0; (j < annotatedRecord.Labels.Count); j++) { if (j == annotatedRecord.Labels.Count - 1) current_activity += ((AXML.Label)annotatedRecord.Labels[j]).Name; else current_activity += ((AXML.Label)annotatedRecord.Labels[j]).Name + "_"; } current_activity = current_activity.Replace("none", "").Replace('-', '_').Replace(':', '_').Replace('%', '_').Replace('/', '_'); current_activity = Regex.Replace(current_activity, "[_]+", "_"); current_activity = Regex.Replace(current_activity, "^[_]+", ""); current_activity = Regex.Replace(current_activity, "[_]+$", ""); } //if (lastTimeStamp>= if (current_activity.Equals("unknown") == false) { if ((Extractor.GenerateFeatureVector(lastTimeStamp))) { string arffSample = Extractor.toString() + "," + current_activity; tw.WriteLine(arffSample); } } } while (isData = aMITesLoggerReader.GetSensorData(10)); tw.Close(); }
public static void toQualityHTML(string aDataDirectory, string masterDirectory, int maxControllers, string[] filter) { int ACCELEROMETER_STATISTICS_LENGTH = 16; //int WOCKETS_SR = 92; int MITES_SR = 45; if (CSVProgress == "") CSVProgress = "Generating Quality Assessment Summary in HTML"; #region =================== Load the MITES/Wockets DATA ============================== //Calculate Data Gaps WocketsController wc = new WocketsController("", "", ""); CurrentWockets._Controller = wc; wc.FromXML(aDataDirectory + "\\" + WOCKETS_SUBDIRECTORY + "\\SensorData.xml"); if (wc._Decoders.Count > 0) { for (int r = 0; (r < wc._Decoders.Count); r++) wc._Decoders[r].Initialize(); } SXML.Reader sreader = null; SXML.SensorAnnotation sannotation = null; try { //JPN!!!!! sreader = new SXML.Reader(masterDirectory, aDataDirectory + "\\" + MITES_SUBDIRECTORY); sannotation = sreader.parse(maxControllers); //remove the HR sensor for (int i = 0; (i < sannotation.Sensors.Count); i++) if ((Convert.ToInt32(((SXML.Sensor)sannotation.Sensors[i]).ID) == 0)) { sannotation.Sensors.RemoveAt(i); break; } } catch { //if there is not mites data, catch the error and continue } #endregion #region ============== Load Annotation Intervals ======================================= Session session = new Session(); session.FromXML(aDataDirectory + "\\" + ANNOTATION_SUBDIRECTORY + "\\" + ANNOTATION_INTERVALS_FILE); int numPostures = 0; Hashtable postures = new Hashtable(); int k = 0; //Think how to handle this when there are more than one activity type Hashtable means_per_class = new Hashtable(); Hashtable std_per_class = new Hashtable(); Hashtable freq_per_class = new Hashtable(); Hashtable min_per_class = new Hashtable(); Hashtable max_per_class = new Hashtable(); //Check if the "unknown" class is specified bool is_unknown_specified = false; //If two categories are available if (session.OverlappingActivityLists.Count == 2) { numPostures = session.OverlappingActivityLists[0].Count * session.OverlappingActivityLists[1].Count + 1; //Go through the activity list for the two categories //This list will generate all combinations of postures-activities for (int i = 0; (i < session.OverlappingActivityLists[1].Count); i++) for (int j = 0; (j < session.OverlappingActivityLists[0].Count); j++) { postures.Add(session.OverlappingActivityLists[1][i]._Name + "_" + session.OverlappingActivityLists[0][j]._Name, k); k++; } } else if (session.OverlappingActivityLists.Count == 1) { numPostures = session.OverlappingActivityLists[0].Count + 1; //Go through the activity list for the available category //This list will simply pass the elements in the category list to the postures data structure for (int i = 0; (i < session.OverlappingActivityLists[0].Count); i++) { if (session.OverlappingActivityLists[0][i]._Name.CompareTo("unknown") == 0) is_unknown_specified = true; postures.Add(session.OverlappingActivityLists[0][i]._Name, k); k++; //initialize the class stats structure means_per_class.Add(session.OverlappingActivityLists[0][i]._Name, (double)0.0); std_per_class.Add(session.OverlappingActivityLists[0][i]._Name, (double)0.0); freq_per_class.Add(session.OverlappingActivityLists[0][i]._Name, (int)0); min_per_class.Add(session.OverlappingActivityLists[0][i]._Name, (double)10000.0); max_per_class.Add(session.OverlappingActivityLists[0][i]._Name, (double)0.0); } } // TODO if four categories present else if (session.OverlappingActivityLists.Count == 4) { numPostures = session.OverlappingActivityLists[0].Count * session.OverlappingActivityLists[1].Count + 1; //Go through the activity list for the two categories //This list will generate all combinations of postures-activities for (int i = 0; (i < session.OverlappingActivityLists[1].Count); i++) for (int j = 0; (j < session.OverlappingActivityLists[0].Count); j++) { postures.Add(session.OverlappingActivityLists[1][i]._Name + "_" + session.OverlappingActivityLists[0][j]._Name, k); k++; } } //Check if postures contain the "unknown" label, otherwise add it if (!is_unknown_specified) { postures.Add("unknown", k); //initialize the class stats structure means_per_class.Add("unknown", (double)0.0); std_per_class.Add("unknown", (double)0.0); freq_per_class.Add("unknown", (int)0); min_per_class.Add("unknown", (double)10000.0); max_per_class.Add("unknown", (double)0.0); } #endregion #region ================= Compute Statistics based on Postures =========================== #region Create Data Structures & Variables int[] timeLostPostureSensorCounter = new int[numPostures]; double[] wocketsSR = new double[wc._Sensors.Count]; double[] trueWocketsSR = new double[wc._Sensors.Count]; double[][] modeWocketsSR = new double[wc._Sensors.Count][]; bool[] disconnected = new bool[wc._Sensors.Count]; double[] zeroWocketsSR = new double[wc._Sensors.Count]; int[] numDisconnected = new int[wc._Sensors.Count]; ArrayList[] disconnectionDistribution = new ArrayList[wc._Sensors.Count]; int[] disconnectionTimer = new int[wc._Sensors.Count]; int[] numDisconnections = new int[wc._Sensors.Count]; int[] meanDisconnection = new int[wc._Sensors.Count]; int[] sdDisconnection = new int[wc._Sensors.Count]; int[][] timeLostPostureSensorDistribution = new int[wc._Sensors.Count][]; int[][] percentLostPostureSensorDistribution = new int[wc._Sensors.Count][]; int[][] percentLostPostureSensorCounter = new int[wc._Sensors.Count][]; int mitesCount = 0; if (sannotation != null) mitesCount = sannotation.Sensors.Count; int[] mitesSR = new int[mitesCount]; int[] trueMitesSR = new int[mitesCount]; int[][] modeMITesSR = new int[mitesCount][]; Hashtable annotatedPostures = new Hashtable(); #endregion #region Initialize Variables // int[] wocketsCounter = new int[wc._Sensors.Count]; // int[] mitesCounter = new int[sannotation.Sensors.Count]; int numSeconds = 0; for (int i = 0; (i < mitesCount); i++) { mitesSR[i] = 0; trueMitesSR[i] = 0; modeMITesSR[i] = new int[1000]; } int mitesStartIndex = 3 + session.OverlappingActivityLists.Count; for (int i = 0; (i < wc._Sensors.Count); i++) { wocketsSR[i] = 0; trueWocketsSR[i] = 0; modeWocketsSR[i] = new double[1000]; disconnected[i] = false; disconnectionDistribution[i] = new ArrayList(); disconnectionTimer[i] = 0; timeLostPostureSensorDistribution[i] = new int[numPostures]; percentLostPostureSensorDistribution[i] = new int[numPostures]; //timeLostPostureSensorCounter[i] = new int[numPostures]; } int wocketsStartIndex = mitesStartIndex + (ACCELEROMETER_STATISTICS_LENGTH * mitesCount); //no heart mites rate if (mitesCount == 0) wocketsStartIndex = wocketsStartIndex - 1; #endregion #region Initialize Annotations & Compute Descripte Statistics int numCategories = session.OverlappingActivityLists.Count; int currentAnnotation = 0; //Get the number of annotations int annotationsLength = session.Annotations.Count; //Get the overall session time double startTime = session.Annotations[0]._StartUnix; double endTime = session.Annotations[annotationsLength - 1]._EndUnix; string name = ""; double duration_secs = 0.0; //Scan annotations and compute the duration min/max stats try { for (int c1 = 0; c1 < annotationsLength; c1++) { name = session.Annotations[c1].Activities[0]._Name; freq_per_class[name] = ((int)freq_per_class[name]) + 1; //compute the duration of the label duration_secs = (session.Annotations[c1]._EndUnix - session.Annotations[c1]._StartUnix) / 1000; means_per_class[name] = ((double)means_per_class[name]) + duration_secs; if (duration_secs < ((double)min_per_class[name])) min_per_class[name] = duration_secs; if (duration_secs > ((double)max_per_class[name])) max_per_class[name] = duration_secs; } //compute the mean for each class for (int c2 = 0; c2 < means_per_class.Count; c2++) { if (c2 < session.OverlappingActivityLists[0].Count) { name = session.OverlappingActivityLists[0][c2]._Name; means_per_class[name] = ((double)means_per_class[name]) / ((int)freq_per_class[name]); } } //Compute the standard deviation of durations for each class for (int c3 = 0; c3 < annotationsLength; c3++) { name = session.Annotations[c3].Activities[0]._Name; //compute the duration of the label duration_secs = (session.Annotations[c3]._EndUnix - session.Annotations[c3]._StartUnix) / 1000; std_per_class[name] = ((double)std_per_class[name]) + Math.Pow((duration_secs - ((double)means_per_class[name])), 2.0); } for (int c4 = 0; c4 < means_per_class.Count; c4++) { if (c4 < session.OverlappingActivityLists[0].Count) { name = session.OverlappingActivityLists[0][c4]._Name; std_per_class[name] = Math.Sqrt(((double)std_per_class[name]) / ((int)freq_per_class[name])); } } } catch { //The computation of the descriptive stats of annotations has failed } #endregion #region Open the Summary CSV File TextReader tr = new StreamReader(aDataDirectory + "\\" + MERGED_SUBDIRECTORY + "\\MITesSummaryData.csv"); string line = ""; tr.ReadLine(); #endregion //Scan the Annotation Intervals and Summary File to Access the Sensors Statistics while ((line = tr.ReadLine()) != null) { //Read Line of Summary File (Sensor Reading) string[] tokens = line.Split(','); double currentTime = Convert.ToDouble(tokens[0]); string posture = tokens[2]; string current_posture = "unknown"; #region Determine if the sensor reading is within the annotation interval & compute its metrics try { // If the sensor reading happens after the end of the annotation interval, // advance to the next annotation if ((currentAnnotation < session.Annotations.Count - 1) && (session.Annotations[currentAnnotation]._EndUnix < currentTime)) currentAnnotation++; // If the sensor reading happens within the annotation interval, // proceed to compute the metrics if ((currentTime >= session.Annotations[currentAnnotation]._StartUnix) && (currentTime <= session.Annotations[currentAnnotation]._EndUnix)) { #region Get the Label Name, Add it to the Hash Table, and Add the Annotated Seconds // If we have more than one category, // make the check for the second category (activities) if (session.Annotations[currentAnnotation].Activities.Count > 1) { //If it is NOT a valid label, replace it for "unknown" if ((session.Annotations[currentAnnotation].Activities[1]._Name == "none") || (session.Annotations[currentAnnotation].Activities[1]._Name == "") || (session.Annotations[currentAnnotation].Activities[1]._Name == "-")) session.Annotations[currentAnnotation].Activities[1]._Name = "unknown"; } //Make the check for all the first category (postures) if ((session.Annotations[currentAnnotation].Activities[0]._Name == "none") || (session.Annotations[currentAnnotation].Activities[0]._Name == "") || (session.Annotations[currentAnnotation].Activities[0]._Name == "-")) session.Annotations[currentAnnotation].Activities[0]._Name = "unknown"; //Get the name of the annotation label if (session.Annotations[currentAnnotation].Activities.Count > 1) current_posture = session.Annotations[currentAnnotation].Activities[1]._Name + "_" + session.Annotations[currentAnnotation].Activities[0]._Name; else current_posture = session.Annotations[currentAnnotation].Activities[0]._Name; // Search in the hash table the name of the current label, // If it doesn't exists, add it to the list of annotated postures // If it exists, add the number of seconds in the annotation if (!annotatedPostures.ContainsKey(current_posture)) annotatedPostures.Add(current_posture, 1); else { int annotatedSeconds = (int)annotatedPostures[current_posture] + 1; annotatedPostures[current_posture] = annotatedSeconds; } #endregion } #region Calculate quality metrics on data that has been annotated only //If the sensor reading falls within the start-end of the session if ((currentTime >= startTime) && (currentTime <= endTime)) { #region Calculate Metrics #region mites SR for (int i = 0; (i < mitesCount); i++) { int sr = Convert.ToInt32(tokens[mitesStartIndex + (ACCELEROMETER_STATISTICS_LENGTH * i)]); mitesSR[i] += sr; modeMITesSR[i][sr] = modeMITesSR[i][sr] + 1; } #endregion #region The number of seconds in a particular posture (adds to the global counter) int currentPostureIndex = 0; currentPostureIndex = (int)postures[current_posture]; timeLostPostureSensorCounter[currentPostureIndex] = timeLostPostureSensorCounter[currentPostureIndex] + 1; #endregion #region wockets SR for (int i = 0; (i < wc._Sensors.Count); i++) { //Compute Wockets Sampling Rate int sr = 0; try { sr = Convert.ToInt32(tokens[wocketsStartIndex + (ACCELEROMETER_STATISTICS_LENGTH * i)]); wocketsSR[i] += sr; modeWocketsSR[i][sr] = modeWocketsSR[i][sr] + 1; } catch (Exception e) { } //Add the samples collected per activity timeLostPostureSensorDistribution[i][currentPostureIndex] = timeLostPostureSensorDistribution[i][currentPostureIndex] + sr; //Compute the number of disconnections if (sr == 0) { zeroWocketsSR[i] = zeroWocketsSR[i] + 1; if (zeroWocketsSR[i] == 5) { disconnected[i] = true; numDisconnected[i] = numDisconnected[i] + 1; } disconnectionTimer[i]++; } else { if (disconnectionTimer[i] >= 5) disconnectionDistribution[i].Add(disconnectionTimer[i]); zeroWocketsSR[i] = 0; disconnected[i] = false; disconnectionTimer[i] = 0; } } #endregion numSeconds++; #endregion } //end of the if #endregion }//end of try catch (Exception e) { //Launch exception when there is a index mistmatch in the ActivityIntervals.xml file } #endregion }//end of while #region Calculate time lost, % data lost, burstiness #region Wockets Loss Calculation //The total session duration int totalSeconds = (int)((endTime - startTime) / 1000.0); //initialize variables int expectedMITesSamples = MITES_SR * totalSeconds; int[] wocketsSecondsLost = new int[wc._Sensors.Count]; int[] mitesSecondsLost = new int[mitesCount]; int[] wocketsPercentLost = new int[wc._Sensors.Count]; int[] mitesPercentLost = new int[mitesCount]; //Compute Loss Based on Sampling Rate and Number of Samples for (int i = 0; (i < wc._Sensors.Count); i++) { int expectedWocketsSamples = wc._Sensors[i]._SamplingRate * totalSeconds; if (wocketsSR[i] < expectedWocketsSamples) { wocketsSecondsLost[i] = (int)Math.Ceiling((double)(expectedWocketsSamples - wocketsSR[i]) / wc._Sensors[i]._SamplingRate); wocketsPercentLost[i] = (int)(((double)wocketsSecondsLost[i] / (double)totalSeconds) * 100.0); } if (disconnectionTimer[i] >= 5) disconnectionDistribution[i].Add(disconnectionTimer[i]); } #endregion Wockets Loss Calculation #region Wockets per Activity Loss Calculation //Scan through the list of annotated postures for (int i = 0; (i < timeLostPostureSensorCounter.Length); i++) { //Scan through the list of sensors for (int j = 0; (j < wc._Sensors.Count); j++) { //expected samples int expectedWocketsSamples = wc._Sensors[j]._SamplingRate * timeLostPostureSensorCounter[i]; //compute loss if (timeLostPostureSensorDistribution[j][i] < expectedWocketsSamples) { timeLostPostureSensorDistribution[j][i] = (int)Math.Floor((expectedWocketsSamples - timeLostPostureSensorDistribution[j][i]) / (double)wc._Sensors[j]._SamplingRate); percentLostPostureSensorDistribution[j][i] = (int)Math.Floor((((double)timeLostPostureSensorDistribution[j][i] / (double)timeLostPostureSensorCounter[i]) * 100.0)); } else { timeLostPostureSensorDistribution[j][i] = 0; percentLostPostureSensorDistribution[j][i] = 0; } } } #endregion Wockets per Activity Loss Calculation #region MEAN and SD Calculation //Iterate through sensors for (int i = 0; (i < wc._Sensors.Count); i++) { numDisconnections[i] = disconnectionDistribution[i].Count; meanDisconnection[i] = 0; for (int j = 0; (j < disconnectionDistribution[i].Count); j++) meanDisconnection[i] = meanDisconnection[i] + (int)disconnectionDistribution[i][j]; if (numDisconnections[i] > 0) meanDisconnection[i] = (meanDisconnection[i] - 1) / numDisconnections[i]; for (int j = 0; (j < disconnectionDistribution[i].Count); j++) sdDisconnection[i] = sdDisconnection[i] + (int)Math.Pow(((double)(int)disconnectionDistribution[i][j] - meanDisconnection[i]), 2.0); if (disconnectionDistribution[i].Count > 1) sdDisconnection[i] = (int)Math.Sqrt(sdDisconnection[i] / (disconnectionDistribution[i].Count - 1)); else sdDisconnection[i] = -1; } #endregion MEAN and SD Calculation #region MITes Loss Calculation for (int i = 0; (i < mitesCount); i++) { if (mitesSR[i] < expectedMITesSamples) mitesSecondsLost[i] = (expectedMITesSamples - mitesSR[i]) / MITES_SR; mitesPercentLost[i] = (int)(((double)mitesSecondsLost[i] / (double)totalSeconds) * 100.0); } #endregion MITes Loss Calculation tr.Close(); #region Percent Maxedout MITES int[] mitesMaxedOut = null; if (sannotation != null) mitesMaxedOut = new int[sannotation.MaximumSensorID + 1]; int[] mitesSamplesCount = null; if (sannotation != null) mitesSamplesCount = new int[sannotation.MaximumSensorID + 1]; try { MITesDecoder aMITesDecoder = new MITesDecoder(); MITesLoggerReader aMITesLoggerReader = new MITesLoggerReader(aMITesDecoder, aDataDirectory + "\\" + MITES_SUBDIRECTORY); bool isData = true; do { //decode the frame int i = aMITesDecoder.GetSomeMITesData()[0].channel; int x = aMITesDecoder.GetSomeMITesData()[0].x; int y = aMITesDecoder.GetSomeMITesData()[0].y; int z = aMITesDecoder.GetSomeMITesData()[0].z; mitesSamplesCount[i] = mitesSamplesCount[i] + 1; if ((x >= 1023) || (y >= 1023) || (z >= 1023)) mitesMaxedOut[i] = mitesMaxedOut[i] + 1; } while (isData = aMITesLoggerReader.GetSensorData(10)); } catch { } #endregion #region Percent Maxed Out Wockets int[] maxedOut = new int[wc._Sensors.Count]; int[] samplesCount = new int[wc._Sensors.Count]; for (int i = 0; (i < wc._Sensors.Count); i++) { wc._Sensors[i]._RootStorageDirectory = aDataDirectory + "\\" + WOCKETS_SUBDIRECTORY + "\\data\\raw\\PLFormat\\"; try { int lastDecodedIndex = 0; while (wc._Sensors[i].Load()) { samplesCount[i] = samplesCount[i] + 1; if (wc._Sensors[i]._Decoder._Head == 0) lastDecodedIndex = wc._Sensors[i]._Decoder._Data.Length - 1; else lastDecodedIndex = wc._Sensors[i]._Decoder._Head - 1; Wockets.Data.Accelerometers.AccelerationData data = (Wockets.Data.Accelerometers.AccelerationData)wc._Sensors[i]._Decoder._Data[lastDecodedIndex]; if ((data._X >= 1023) || (data._Y >= 1023) || (data._Z >= 1023)) maxedOut[i] = maxedOut[i] + 1; } } catch (Exception e) { } } #endregion Percent Maxed Out Wockets #region Write Results to HTML string summary = "<h3><Font Color=#585858>MITes and Wockets Data Loss, Disconnections and Maxing out Statistics </Font></h3><TABLE border=\"1\">\n"; int numRows = wc._Sensors.Count - 1 + mitesCount; string[] rows = new string[numRows]; string header = "<TR>\n"; string[] hlabels = new string[] { "Placement\\Metric", "Data Loss (seconds)", "% Data Loss", "Num Disconnections", "Mean Disconnection (seconds)", "SD Disconnection (seconds)", "Num Maxed Out", "% Maxed Out" }; for (int i = 0; (i < hlabels.Length); i++) header += "<TD><div align=\"center\"><strong>" + hlabels[i] + "</strong></div></TD>\n"; header += "</TR>\n"; summary += header; #region Statistics Table for MITES for (int i = 0; (i < mitesCount); i++) { string row = "<TR>\n"; row += "<TD><div align=\"center\"><strong>MITes " + ((SXML.Sensor)sannotation.Sensors[i]).Location + "</strong></div></TD>\n"; if (mitesPercentLost[i] >= 20) { row += "<TD bgcolor=\"#FF0000\"><div align=\"center\">" + mitesSecondsLost[i].ToString() + "</div></TD>\n"; ; row += "<TD bgcolor=\"#FF0000\"><div align=\"center\">" + mitesPercentLost[i].ToString() + "%" + "</div></TD>\n"; } else { row += "<TD><div align=\"center\">" + mitesSecondsLost[i].ToString() + "</div></TD>\n"; ; row += "<TD><div align=\"center\">" + mitesPercentLost[i].ToString() + "%" + "</div></TD>\n"; } int percent = 0; if (mitesSamplesCount[Convert.ToInt32(((SXML.Sensor)sannotation.Sensors[i]).ID)] > 0) percent = (int)(((double)mitesMaxedOut[Convert.ToInt32(((SXML.Sensor)sannotation.Sensors[i]).ID)] / (double)mitesSamplesCount[Convert.ToInt32(((SXML.Sensor)sannotation.Sensors[i]).ID)]) * 100.0); row += "<TD><div align=\"center\">" + "N/A" + "</div></TD>\n"; row += "<TD><div align=\"center\">" + "N/A" + "</div></TD>\n"; row += "<TD><div align=\"center\">" + "N/A" + "</div></TD>\n"; row += "<TD><div align=\"center\">" + mitesMaxedOut[Convert.ToInt32(((SXML.Sensor)sannotation.Sensors[i]).ID)] + "</div></TD>\n"; row += "<TD><div align=\"center\">" + percent + "% </div></TD>\n"; row += "</TR>\n"; summary += row; } summary += "<TR><TD colspan=\"8\"></TD></TR><TR>\n"; #endregion #region Statistics Table for Wockets for (int i = 0; (i < wc._Sensors.Count); i++) { if (wc._Receivers[i] is Wockets.Receivers.RFCOMMReceiver) { string row = "<TR>\n"; row += "<TD><div align=\"center\"><strong>Wocket " + wc._Sensors[i]._Location + "</strong></div></TD>\n"; if (wocketsPercentLost[i] >= 20) { row += "<TD bgcolor=\"#FF0000\"><div align=\"center\">" + wocketsSecondsLost[i].ToString() + "</div></TD>\n"; row += "<TD bgcolor=\"#FF0000\"><div align=\"center\">" + wocketsPercentLost[i].ToString() + "%" + "</div></TD>\n"; } else { row += "<TD><div align=\"center\">" + wocketsSecondsLost[i].ToString() + "</div></TD>\n"; row += "<TD><div align=\"center\">" + wocketsPercentLost[i].ToString() + "%" + "</div></TD>\n"; } row += "<TD><div align=\"center\">" + numDisconnections[i].ToString() + "</div></TD>\n"; row += "<TD><div align=\"center\">" + meanDisconnection[i].ToString() + "</div></TD>\n"; if (sdDisconnection[i] >= 0) row += "<TD><div align=\"center\">" + sdDisconnection[i].ToString() + "</div></TD>\n"; else row += "<TD><div align=\"center\">N/A</div></TD>\n"; row += "<TD><div align=\"center\">" + maxedOut[i].ToString() + "</div></TD>\n"; if (samplesCount[i] > 0) row += "<TD><div align=\"center\">" + ((int)(((double)maxedOut[i] / (double)samplesCount[i]) * 100.0)).ToString() + "% </div></TD>\n"; else row += "<TD><div align=\"center\">0% </div></TD>\n"; row += "</TR>\n"; summary += row; } } summary += "</TABLE>\n"; summary = "<HTML><HEAD></HEAD><BODY>" + summary + "</BODY></HTML>"; TextWriter tw = new StreamWriter(aDataDirectory + "\\result.html", true); tw.WriteLine(summary); tw.WriteLine("\n<p> </p>\n"); #endregion #region Statistics per Activity Table summary = "<h3><Font Color=#585858>Wockets Data Loss by Posture and Activity Statistics</Font></h3><TABLE border=\"1\">\n"; numRows = numPostures; rows = new string[numRows]; header = "<TR>\n<td><div align=\"center\"><strong>Activity</strong></div></td><td><div align=\"center\"><strong>Posture</strong></div></td><td><strong>Total Seconds Annotated</strong></td>\n"; for (int j = 0; (j < wc._Sensors.Count); j++) header += "<TD><div align=\"center\"><strong>" + wc._Sensors[j]._Location + "</br>(Seconds Lost|% Lost)</strong></div></TD>\n"; header += "</TR>\n"; summary += header; int m = 0; if (session.OverlappingActivityLists.Count > 1) { for (int i = 0; (i < session.OverlappingActivityLists[1].Count); i++) for (int j = 0; (j < session.OverlappingActivityLists[0].Count); j++) { if (annotatedPostures.ContainsKey(session.OverlappingActivityLists[1][i]._Name + "_" + session.OverlappingActivityLists[0][j]._Name)) { string row = "<TR>\n"; row += "<TD><div align=\"center\"><strong>" + session.OverlappingActivityLists[1][i]._Name + "</strong></div></TD><TD><div align=\"center\"><strong>" + session.OverlappingActivityLists[0][j]._Name + "</strong></div></TD>\n"; row += "<TD><div>" + (int)annotatedPostures[session.OverlappingActivityLists[1][i]._Name + "_" + session.OverlappingActivityLists[0][j]._Name] + "</TD>\n"; for (int r = 0; (r < wc._Sensors.Count - 1); r++) if (percentLostPostureSensorDistribution[r][m] > 20) row += "<TD bgcolor=\"#FF0000\"><div align=\"center\">" + timeLostPostureSensorDistribution[r][m].ToString() + " | " + percentLostPostureSensorDistribution[r][m].ToString() + "%" + "</div></TD>\n"; else row += "<TD ><div align=\"center\">" + timeLostPostureSensorDistribution[r][m].ToString() + " | " + percentLostPostureSensorDistribution[r][m].ToString() + "%" + "</div></TD>\n"; row += "</TR>\n"; summary += row; } m++; } } else { for (int j = 0; (j < session.OverlappingActivityLists[0].Count); j++) { if (annotatedPostures.ContainsKey(session.OverlappingActivityLists[0][j]._Name)) { string row = "<TR>\n"; row += "<TD><div align=\"center\"><strong>" + session.OverlappingActivityLists[0][j]._Name + "</strong></div></TD><TD><div align=\"center\"><strong>" + session.OverlappingActivityLists[0][j]._Name + "</strong></div></TD>\n"; row += "<TD><div>" + (int)annotatedPostures[session.OverlappingActivityLists[0][j]._Name] + "</TD>\n"; for (int r = 0; (r < wc._Sensors.Count); r++) if (percentLostPostureSensorDistribution[r][m] > 20) row += "<TD bgcolor=\"#FF0000\"><div align=\"center\">" + timeLostPostureSensorDistribution[r][m].ToString() + " | " + percentLostPostureSensorDistribution[r][m].ToString() + "%" + "</div></TD>\n"; else row += "<TD ><div align=\"center\">" + timeLostPostureSensorDistribution[r][m].ToString() + " | " + percentLostPostureSensorDistribution[r][m].ToString() + "%" + "</div></TD>\n"; row += "</TR>\n"; summary += row; } m++; } } tw.WriteLine(summary + "</TABLE>\n"); #endregion #region Other Sensors Statistics Table string[] ofiles = Directory.GetFileSystemEntries(aDataDirectory + "\\" + OTHER_SUBDIRECTORY + "\\"); if (ofiles.Length > 1) { summary = "<h3><Font Color=#585858>Other Sensors Statistics</Font></h3><TABLE border=\"1\">\n"; header = "<TR>\n<td><div align=\"center\"><strong>Sensor Type</strong></div></td><td><div align=\"center\"><strong>Start Time</strong></div></td><td><strong>Data Present</strong></td><td><strong>Num Samples</strong></td><td><strong>Percent Loss</strong></td></TR>\n"; header += "</TR>\n"; summary += header; int expectedOxyconRecords = totalSeconds / 5; double oxyconLoss = 0; if (oxyconRecords < expectedOxyconRecords) oxyconLoss = 100 - (((double)oxyconRecords / expectedOxyconRecords) * 100.0); summary += "<TR>\n<td><div align=\"center\"><strong>Oxycon</strong></div></td><td>" + (oxyconStart == null ? " " : oxyconStart) + "</td><td>" + (hasOxycon ? "Yes" : "No") + "</td><td>" + oxyconRecords + "</td><td>" + oxyconLoss.ToString("0") + "%</td></TR>\n"; double sensewearLoss = 0; if (sensewearRecords < totalSeconds) sensewearLoss = 100 - (((double)sensewearRecords / totalSeconds) * 100.0); summary += "<TR>\n<td><div align=\"center\"><strong>Sensewear</strong></div></td><td>" + (sensewearStart == null ? " " : sensewearStart) + "</td><td>" + (hasSensewear ? "Yes" : "No") + "</td><td>" + sensewearRecords + "</td><td>" + sensewearLoss.ToString("0") + "%</td></TR>\n"; summary += "<TR>\n<td><div align=\"center\"><strong>Actigraph</strong></div></td><td>" + (actigraphStart == null ? " " : actigraphStart) + "</td><td>" + (hasActigraph ? "Yes" : "No") + "</td><td>"; for (int r = 0; (r < actigraphData.Length); r++) { summary += actigraphData[r].Count; if (r != (actigraphData.Length - 1)) summary += " | "; } summary += "</td><td>"; for (int r = 0; (r < actigraphData.Length); r++) { double actigraphLoss = 0; if (actigraphData[r].Count < totalSeconds) actigraphLoss = 100 - (((double)actigraphData[r].Count / totalSeconds) * 100.0); summary += actigraphLoss.ToString("0") + " %"; if (r != (actigraphData.Length - 1)) summary += " | "; } summary += "</td></TR>\n"; double zephyrLoss = 0; if (zephyrRecords < totalSeconds) zephyrLoss = 100 - (((double)zephyrRecords / totalSeconds) * 100.0); summary += "<TR>\n<td><div align=\"center\"><strong>Zephyr</strong></div></td><td>" + (zephyrStart == null ? " " : zephyrStart) + "</td><td>" + (hasZephyr ? "Yes" : "No") + "</td><td>" + zephyrRecords + "</td><td>" + zephyrLoss.ToString("0") + "%</td></TR>\n"; double rtiLoss = 0; if (rtiRecords < totalSeconds) rtiLoss = 100 - (((double)rtiRecords / totalSeconds) * 100.0); summary += "<TR>\n<td><div align=\"center\"><strong>RTI</strong></div></td><td>" + (rtiStart == null ? " " : rtiStart) + "</td><td>" + (hasRTI ? "Yes" : "No") + "</td><td>" + rtiRecords + "</td><td>" + rtiLoss.ToString("0") + "%</td></TR>\n"; double columbiaLoss = 0; if (columbiaRecords < totalSeconds) columbiaLoss = 100 - (((double)columbiaRecords / totalSeconds) * 100.0); summary += "<TR>\n<td><div align=\"center\"><strong>Columbia</strong></div></td><td>" + (columbiaStart == null ? " " : columbiaStart) + "</td><td>" + (hasColumbia ? "Yes" : "No") + "</td><td>" + columbiaRecords + "</td><td>" + columbiaLoss.ToString("0") + "%</td></TR>\n"; double gpsLoss = 0; if (gpsRecords < totalSeconds) gpsLoss = 100 - (((double)gpsRecords / totalSeconds) * 100.0); summary += "<TR>\n<td><div align=\"center\"><strong>GPS</strong></div></td><td>" + (gpsStart == null ? " " : gpsStart) + "</td><td>" + (hasGPS ? "Yes" : "No") + "</td><td>" + gpsRecords + "</td><td>" + gpsLoss.ToString("0") + "%</td></TR>\n"; tw.WriteLine(summary + "</TABLE>\n"); } #endregion tw.WriteLine("</HTML>"); tw.Flush(); tw.Close(); #endregion #region Add the Annotations Summary tw = new StreamWriter(aDataDirectory + "\\result.html", true); summary = ""; summary += "<h3><Font Color=#585858>Annotation Summary</Font></h3>\n"; //If the annotation summary file exists, add it to current summary //If it doesn't exist, add the HTML to summary if (File.Exists(aDataDirectory + "\\" + ANNOTATION_SUBDIRECTORY + "\\AnnotationSummary.html")) { try { TextReader ttr = new StreamReader(aDataDirectory + "\\" + ANNOTATION_SUBDIRECTORY + "\\AnnotationSummary.html"); summary += ttr.ReadToEnd(); ttr.Close(); } catch (Exception ee) { } } else { #region Create HTML content with stats for Autism Data try { //Create Table & Headers summary += "<table border=\"1\">\n"; TimeSpan ttime = new TimeSpan(0, 0, totalSeconds); //Session total time summary += "<tr> <td><div align=\"center\"><strong>Session Total Time (hh:mm:ss.ms)</strong></div></td>" + "<td>" + String.Format("{0:HH mm ss ff}", ttime) + "</td>" + "</tr>"; //Headers for annotation metrics summary += "<tr>" + "<td><div align=\"center\"><strong> Label </strong></div></td>" + "<td><div align=\"center\"><strong> Duration in Seconds </strong></div></td>" + "<td><div align=\"center\"><strong> %Occurrence </strong></div></td>" + "<td><div align=\"center\"><strong> Frequency </strong></div></td>" + "<td><div align=\"center\"><strong> Mean (sec) </strong></div></td>" + "<td><div align=\"center\"><strong> STD (sec) </strong></div></td>" + "<td><div align=\"center\"><strong> Min (sec) </strong></div></td>" + "<td><div align=\"center\"><strong> Max (sec) </strong></div></td>" + "</tr>"; //Scan through labels int total_secs_activity = 0; double percent_duration = 0.0; for (int j = 0; j < session.OverlappingActivityLists[0].Count; j++) { name = session.OverlappingActivityLists[0][j]._Name; if (annotatedPostures.ContainsKey(name)) { total_secs_activity = (int)annotatedPostures[name]; percent_duration = ((double)total_secs_activity / totalSeconds) * 100.0; summary += "<tr>\n" + "<td><div align=\"center\"><strong>" + name + "</strong></div></td>" + "<td>" + total_secs_activity.ToString() + "</td>" + "<td>" + String.Format("{0:0.0}%", percent_duration) + "</td>" + "<td>" + String.Format("{0:0}", freq_per_class[name]) + "</td>" + "<td>" + String.Format("{0:0.00}", means_per_class[name]) + "</td>" + "<td>" + String.Format("{0:0.00}", std_per_class[name]) + "</td>" + "<td>" + String.Format("{0:0.00}", min_per_class[name]) + "</td>" + "<td>" + String.Format("{0:0.00}", max_per_class[name]) + "</td>" + "</tr>"; } else { summary += "<tr>\n" + "<td><div align=\"center\"><strong>" + name + "</strong></div></td>" + "<td>" + String.Format("{0:0}", 0) + "</td>" + "<td>" + String.Format("{0:0.0}%", 0) + "</td>" + "<td>" + String.Format("{0:0}", 0) + "</td>" + "<td>" + String.Format("{0:0.00}", 0) + "</td>" + "<td>" + String.Format("{0:0.00}", 0) + "</td>" + "<td>" + String.Format("{0:0.00}", 0) + "</td>" + "<td>" + String.Format("{0:0.00}", 0) + "</td>" + "</tr>"; } } //Close table summary += "</table>"; //Generate the colors code for Autistic Labels SaveLabelsColorsToFile(aDataDirectory, session.OverlappingActivityLists.Count, session.OverlappingActivityLists); } catch (Exception ee) { summary += "</HTML>"; try { if (tw != null) { tw.WriteLine(summary); tw.Close(); } } catch (Exception ex) { //cannot write to file } } #endregion } summary += "</HTML>"; #endregion tw.WriteLine(summary); tw.Close(); #endregion #endregion }