using System; using System.Collections.Generic; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.DataPreprocessing.Interfaces; using HeuristicLab.Problems.DataAnalysis; using HeuristicLab.Problems.DataAnalysis.Transformations; namespace HeuristicLab.DataPreprocessing.Implementations { public class FilteredPreprocessingData : NamedItem, IFilteredPreprocessingData { private readonly ITransactionalPreprocessingData originalData; private ITransactionalPreprocessingData filteredData; public IDictionary> Selection { get { return originalData.Selection; } set { originalData.Selection = value; } } protected FilteredPreprocessingData(FilteredPreprocessingData original, Cloner cloner) : base(original, cloner) { originalData = original.originalData; filteredData = original.filteredData; } public FilteredPreprocessingData(ITransactionalPreprocessingData preporcessingData) : base() { originalData = preporcessingData; filteredData = null; } public override IDeepCloneable Clone(Cloner cloner) { return new FilteredPreprocessingData(this, cloner); } public T GetCell(int columnIndex, int rowIndex) { return ActiveData.GetCell(columnIndex, rowIndex); } public void SetCell(int columnIndex, int rowIndex, T value) { if (IsFiltered) throw new InvalidOperationException("SetCell not possible while data is filtered"); originalData.SetCell(columnIndex, rowIndex, value); } public string GetCellAsString(int columnIndex, int rowIndex) { return ActiveData.GetCellAsString(columnIndex, rowIndex); } public IList GetValues(string variableName, bool considerSelection) { return ActiveData.GetValues(variableName, considerSelection); } public IList GetValues(int columnIndex, bool considerSelection) { return ActiveData.GetValues(columnIndex, considerSelection); } public void SetValues(int columnIndex, IList values) { if (IsFiltered) throw new InvalidOperationException("SetValues not possible while data is filtered"); originalData.SetValues(columnIndex, values); } public void InsertRow(int rowIndex) { if (IsFiltered) throw new InvalidOperationException("InsertRow not possible while data is filtered"); originalData.InsertRow(rowIndex); } public void DeleteRow(int rowIndex) { if (IsFiltered) throw new InvalidOperationException("DeleteRow not possible while data is filtered"); originalData.DeleteRow(rowIndex); } public void InsertColumn(string variableName, int columnIndex) { if (IsFiltered) throw new InvalidOperationException("InsertColumn not possible while data is filtered"); originalData.InsertColumn(variableName, columnIndex); } public void DeleteColumn(int columnIndex) { if (IsFiltered) throw new InvalidOperationException("DeleteColumn not possible while data is filtered"); originalData.DeleteColumn(columnIndex); } public IntRange TrainingPartition { get { return originalData.TrainingPartition; } } public IntRange TestPartition { get { return originalData.TestPartition; } } public IList Transformations { get { return originalData.Transformations; } } public IEnumerable VariableNames { get { return ActiveData.VariableNames; } } public string GetVariableName(int columnIndex) { return ActiveData.GetVariableName(columnIndex); } public int GetColumnIndex(string variableName) { return ActiveData.GetColumnIndex(variableName); } public bool IsType(int columnIndex) { return originalData.IsType(columnIndex); } public int Columns { get { return ActiveData.Columns; } } public int Rows { get { return ActiveData.Rows; } } public Dataset ExportToDataset() { return originalData.ExportToDataset(); } public void SetFilter(bool[] rowFilters) { filteredData = (ITransactionalPreprocessingData)originalData.Clone(); filteredData.InTransaction(() => { for (int row = (rowFilters.Length - 1); row >= 0; --row) { if (rowFilters[row]) { filteredData.DeleteRow(row); } } }); OnFilterChanged(); } public void PersistFilter() { originalData.InTransaction(() => { for (int i = 0; i < filteredData.Columns; ++i) { if (filteredData.IsType(i)) { originalData.SetValues(i, filteredData.GetValues(i)); } else if (filteredData.IsType(i)) { originalData.SetValues(i, filteredData.GetValues(i)); } else if (filteredData.IsType(i)) { originalData.SetValues(i, filteredData.GetValues(i)); } else { throw new ArgumentException("Data types of columns do not match"); } } }); ResetFilter(); } public void ResetFilter() { filteredData = null; OnFilterChanged(); } private void OnFilterChanged() { if (FilterChanged != null) { FilterChanged(this, new EventArgs()); } } public ITransactionalPreprocessingData ActiveData { get { return IsFiltered ? filteredData : originalData; } } public bool IsUndoAvailable { get { return IsFiltered ? false : originalData.IsUndoAvailable; } } public bool IsFiltered { get { return filteredData != null; } } public event DataPreprocessingChangedEventHandler Changed { add { originalData.Changed += value; } remove { originalData.Changed -= value; } } public void Undo() { if (IsFiltered) throw new InvalidOperationException("Undo not possible while data is filtered"); originalData.Undo(); } public void InTransaction(Action action, DataPreprocessingChangedEventType type = DataPreprocessingChangedEventType.Any) { if (IsFiltered) throw new InvalidOperationException("Transaction not possible while data is filtered"); originalData.InTransaction(action, type); } public void BeginTransaction(DataPreprocessingChangedEventType type) { if (IsFiltered) throw new InvalidOperationException("Transaction not possible while data is filtered"); originalData.BeginTransaction(type); } public void EndTransaction() { originalData.EndTransaction(); } public event EventHandler FilterChanged; #region IPreprocessingData Members public void ClearSelection() { originalData.ClearSelection(); } public event EventHandler SelectionChanged { add { originalData.SelectionChanged += value; } remove { originalData.SelectionChanged -= value; } } #endregion #region IPreprocessingData Members public IEnumerable GetDoubleVariableNames() { return originalData.GetDoubleVariableNames(); } #endregion } }