/// <summary> /// Calculate feature value from a unidimensional sample-based feature /// </summary> void SampleBasedCalculation() { // Check that data is available if (timestamps.Count == 0 && dataBuffer.Count == 0) { // ExciteOMeterManager.DebugLog("No timestamps or data were found to calculate features"); ExciteOMeterManager.LogInFile("No incoming data " + incomingDataType.ToString() + " was found to calculate feature " + outputDataType.ToString()); return; } // Calculate feature featureValue = CalculateFeature(timestamps.ToArray(), dataBuffer.ToArray()); // Calculate offset of timestamp that corresponds to the calculated feature (# displacements to the left in timestamps) // Examples: Assume `sampleBuffer=5` // If `offsetSamplesTimestamp=0`, t for calculated feature is [t-4,t-3,...,t] // If `offsetSamplesTimestamp=3`, t for calculated feature is [t-1,t,t+1,t+2,t+3] indexOffsetForTimestamp = sampleBuffer - offsetSamplesTimestamp - 1; // Send events and log in file ExciteOMeterManager.DebugLog("A new feature was calculated in " + outputDataType.ToString() + ": " + timestamps[indexOffsetForTimestamp] + ", " + featureValue.ToString()); // Flag to know if it is the first calculation of the feature. // If so, the new feature has to match all the timestamps existing before the first timestamp of the feature. if (matchLengthOfInputSignal) { if (isFirstCalculatedFeature) { isFirstCalculatedFeature = false; idxStartRepeating = 0; // No previous data in array, repeat from beginning of input timestamps. } else { // CASE: Match length and buffer already contains data from previous window // Based on overlap and offset, the position where to start repeating timestamps is the following formula. idxStartRepeating = overlappingSamples - offsetSamplesTimestamp; } // Fill the previous timestamps of the input signal with the same value of this feature. for (int i = idxStartRepeating; i <= indexOffsetForTimestamp; i++) { // Write in files to collect data corresponding to EoM_Events.Send_OnDataReceived(outputDataType, timestamps[i], featureValue); LoggerController.instance.WriteLine(logIdentifier, ExciteOMeterManager.ConvertFloatToString(timestamps[i]) + "," + ExciteOMeterManager.ConvertFloatToString(featureValue)); } } else { Debug.LogWarning("Error calculating feature. Matching sampling error: logIdentifier" + logIdentifier.ToString()); //// CASE: DO NOT MATCH LENGTH OF INPUT SIGNAL, BUT USE TIMESTAMP DIFFERENT THAN LAST SAMPLE //EoM_Events.Send_OnDataReceived(outputDataType, timestamps[indexOffsetForTimestamp], featureValue); //LoggerController.instance.WriteLine(logIdentifier, ExciteOMeterManager.ConvertFloatToString(timestamps[indexOffsetForTimestamp]) + "," + ExciteOMeterManager.ConvertFloatToString(featureValue)); } // Rearrange overlap in signal elementsToDelete = sampleBuffer - overlappingSamples; timestamps.RemoveRange(0, elementsToDelete); dataBuffer.RemoveRange(0, elementsToDelete); }
void ProcessStringLog(ExciteOMeter.DataType type, float timestamp, string message, MarkerLabel label) { bool written = LoggerController.instance.WriteLine(LogName.EventsAndMarkers, ExciteOMeterManager.ConvertFloatToString(timestamp) + "," + type.ToString() + "," + message + "," + label.ToString()); if (!written) { Debug.LogWarning("The Logger Controller has not been setup to store strings. Please setup a file with LogID EventsAndMarkers."); } }
// Start is called before the first frame update void Start() { // PostProcessing flag numInstances++; // Default values, if this needs to be changed per feature reimplementing the following function in the child class isTimeBasedFeature = !SettingsManager.Values.featureSettings.DEFAULT_IS_SAMPLE_BASED; windowTime = SettingsManager.Values.featureSettings.DEFAULT_WINDOW_TIME_SECS; overlappingFraction = SettingsManager.Values.featureSettings.DEFAULT_OVERLAP_FRACTION; isSampleBasedFeature = SettingsManager.Values.featureSettings.DEFAULT_IS_SAMPLE_BASED; sampleBuffer = SettingsManager.Values.featureSettings.DEFAULT_SAMPLE_BUFFER; overlappingSamples = SettingsManager.Values.featureSettings.DEFAULT_OVERLAP_SAMPLES; offsetSamplesTimestamp = SettingsManager.Values.featureSettings.DEFAULT_OFFSET_SAMPLES_TIMESTAMP; // Only for sample-based, whether input and output are forced to have same length by resampling data. matchLengthOfInputSignal = SettingsManager.Values.featureSettings.matchInputOutputLength; // CONDITIONS if (isSampleBasedFeature) { if (overlappingSamples >= sampleBuffer) { // Error, the number of samples to delete ExciteOMeterManager.LogInFile("The samples to delete in buffer feature " + outputDataType.ToString() + " are larger than sampleBufferLength. Check config.json"); overlappingSamples = 0; } else if (offsetSamplesTimestamp > overlappingSamples) { ExciteOMeterManager.LogInFile("The offset timestamp of timestamp in feature " + outputDataType.ToString() + " needs to be lower than overlapSamplesLength. Check config.json"); offsetSamplesTimestamp = 0; } } // If there are some configurations needed for the specific feature SetupStart(); }
private void ExciteOMeterDataReceived(ExciteOMeter.DataType type, float timestamp, float value) { // Only process data when a file is configured if (!isConfigured) { return; } try { Values.timeseries[type].timestamp.Add(timestamp); Values.timeseries[type].value.Add(value); } catch (Exception) { Debug.Log("Omitted data point > Data Type: " + type.ToString() + " - Timestamp: " + timestamp + " - Value: " + value); } }