/// <summary> /// Filter the specified phaseInput. /// </summary> /// <returns>The filter.</returns> /// <param name="phaseInput">Phase input.</param> public IEnumerable <PhaseData <SensorReading> > Filter(PhaseInput <SensorReading> phaseInput) { var results = new List <PhaseData <SensorReading> >(); foreach (var input in phaseInput.Input) { // input = name plus collection of data records foreach (var record in input.Data) { // each data record is a single sensor reading foreach (var param in phaseInput.Parameters) { // check to see if desired field exists for this reading // if not, proceed to next parameter var filterField = record.GetType().GetProperty(param.Field); if (filterField == null) { continue; } // if it does exist, check to see if value satisfies clause // collection for this parameter ... var filterValue = filterField.GetValue(record, null).ToString(); var isMatch = param.MatchesClause(filterValue); // if we fail to match, start over with next record // (ends parameter for-each) if (!isMatch) { break; } // if valid match AND user chose to split output, // update result names to produce output split string resultName = (param.UseOutputSplit() ? FilterManager.GetFilterFilename(input.Name, filterValue) : input.Name); if (!results.Select(x => x.Name).Contains(resultName)) { var newResult = new PhaseData <SensorReading> { Name = resultName, Data = new List <SensorReading> { record } }; results.Add(newResult); } else { var existingResult = results.Where(x => x.Name.Equals(resultName)).FirstOrDefault(); existingResult.Data.Add(record); } } } } return(results); }
/// <summary> /// Filter the specified phaseInput. /// </summary> /// <returns>The filter.</returns> /// <param name="phaseInput">Phase input.</param> public IEnumerable <PhaseData <SensorReading> > Filter(PhaseInput <SensorReading> phaseInput) { CalibratedThresholds = new List <KeyValuePair <string, decimal> >(); var calibrationResults = new List <CalibrationResult>(); foreach (var input in phaseInput.Input) { foreach (var param in phaseInput.Parameters) { var calibrationField = typeof(SensorReading).GetProperty(param.Field); var fieldTypeCode = Type.GetTypeCode(calibrationField.PropertyType); var calibStep = param.GetClauseValue(CommandParameters.Step); var calibPercentage = param.GetClauseValue(CommandParameters.Percentage); if (fieldTypeCode == TypeCode.Decimal && calibStep != null && calibPercentage != null) { var calibRecords = input.Data.Where(x => x.Label.Contains(calibStep)).ToList(); var calibVals = calibRecords.Select(x => (decimal)calibrationField.GetValue(x, null)).ToList(); var avgVal = MathService.Average(calibVals); var threshVal = avgVal * (decimal.Parse(calibPercentage) / 100.0M); CalibratedThresholds.Add(new KeyValuePair <string, decimal>(param.Field, threshVal)); calibrationResults.Add(new CalibrationResult { Source = input.Name, AvgVal = avgVal, ThresholdVal = threshVal }); } } // dump own results to file CsvFileWriter.WriteResultsToFile (new string[] { OutputDirs.Filters, "ThresholdCalibration" }, input.Name, HeaderCsv, calibrationResults); } // return empty list ... we don't actually want to // affect the post-phase data set return(new List <PhaseData <SensorReading> >()); }
public virtual void Input(PhaseInput input) { }
/// <summary> /// Filter the specified phaseInput. /// </summary> /// <returns>The filter.</returns> /// <param name="phaseInput">Phase input.</param> public IEnumerable <PhaseData <SensorReading> > Filter(PhaseInput <SensorReading> phaseInput) { var param = phaseInput.Parameters.FirstOrDefault(); if (param == null) { return(null); } var filterField = typeof(SensorReading).GetProperty(param.Field); var success = decimal.TryParse(param.GetClauseValue(CommandParameters.Percentage), out decimal completionPercentage); if (filterField == null || !success) { return(null); } // find a list of distinct values of the desired field across all data sets var distinctValues = phaseInput.Input.Select(x => x.Data.Select(y => Parameter.GetFilterValue(filterField, y))).SelectMany(x => x).Distinct().ToList(); // only include records from a given data set whose field values // are present in a matching percentage of the other data sets for (int i = distinctValues.Count() - 1; i >= 0; i--) { var distinctValue = distinctValues[i]; var matchingDataSetCount = phaseInput.Input.Count(x => x.Data.Select(y => Parameter.GetFilterValue(filterField, y)).Contains(distinctValue)); var matchingPercentage = ((decimal)matchingDataSetCount / (decimal)phaseInput.Input.Count()) * 100.0M; if (matchingPercentage < completionPercentage) { distinctValues.RemoveAt(i); } } // double check ... LogManager.Info("The following distinct field values were found for Completion Filter:\n\t" + string.Join("\n\t", distinctValues), this); // proceed with results gathering ... var results = new List <PhaseData <SensorReading> >(); foreach (var input in phaseInput.Input) { foreach (var record in input.Data) { var filterValue = Parameter.GetFilterValue(filterField, record); var isMatch = distinctValues.Contains(filterValue); if (!isMatch) { continue; } // if valid match AND user chose to split output, // update result names to produce output split string resultName = (param.UseOutputSplit() ? FilterManager.GetFilterFilename(input.Name, filterValue) : input.Name); // add the data to the results list if (!results.Select(x => x.Name).Contains(resultName)) { var newResult = new PhaseData <SensorReading> { Name = resultName, Data = new List <SensorReading> { record } }; results.Add(newResult); } else { var existingResult = results.Where(x => x.Name.Equals(resultName)).FirstOrDefault(); existingResult.Data.Add(record); } } } return(results); }