#region License Information
/* HeuristicLab
* Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* HeuristicLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with HeuristicLab. If not, see .
*/
#endregion
using System;
using System.Collections.Generic;
using HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
using HeuristicLab.Problems.DataAnalysis;
namespace HeuristicLab.DataPreprocessing {
[Item("FilteredPreprocessingData", "Represents filtered data used for preprocessing.")]
[StorableClass]
public sealed class FilteredPreprocessingData : NamedItem, IFilteredPreprocessingData {
[Storable]
private readonly IPreprocessingData originalData;
[Storable]
private IPreprocessingData filteredData;
public IList DataColumns {
get { return ActiveData.DataColumns; }
}
public IPreprocessingData ActiveData {
get { return IsFiltered ? filteredData : originalData; }
}
#region Constructor, Cloning & Persistence
public FilteredPreprocessingData(IPreprocessingData preporcessingData)
: base() {
originalData = preporcessingData;
filteredData = null;
}
private FilteredPreprocessingData(FilteredPreprocessingData original, Cloner cloner)
: base(original, cloner) {
originalData = original.originalData;
filteredData = original.filteredData;
}
public override IDeepCloneable Clone(Cloner cloner) {
return new FilteredPreprocessingData(this, cloner);
}
[StorableConstructor]
private FilteredPreprocessingData(bool deserializing)
: base(deserializing) { }
#endregion
#region Cells
public bool IsCellEmpty(int columnIndex, int rowIndex) {
return ActiveData.IsCellEmpty(columnIndex, rowIndex);
}
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("SetValues not possible while data is filtered");
originalData.SetCell(columnIndex, rowIndex, value);
}
public string GetCellAsString(int columnIndex, int rowIndex) {
return ActiveData.GetCellAsString(columnIndex, rowIndex);
}
public IEnumerable GetValues(int columnIndex, bool considerSelection) {
return ActiveData.GetValues(columnIndex, considerSelection);
}
public void SetValues(int columnIndex, IEnumerable values) {
if (IsFiltered)
throw new InvalidOperationException("SetValues not possible while data is filtered");
originalData.SetValues(columnIndex, values);
}
public bool SetValue(string value, int columnIndex, int rowIndex) {
if (IsFiltered)
throw new InvalidOperationException("SetValue not possible while data is filtered");
return originalData.SetValue(value, columnIndex, rowIndex);
}
public int Columns {
get { return ActiveData.Columns; }
}
public int Rows {
get { return ActiveData.Rows; }
}
#endregion
#region Rows
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 DeleteRows(IEnumerable rows) {
if (IsFiltered)
throw new InvalidOperationException("DeleteRowsWithIndices not possible while data is filtered");
originalData.DeleteRows(rows);
}
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 void RenameColumn(int columnIndex, string name) {
if (IsFiltered)
throw new InvalidOperationException("RenameColumn not possible while data is filtered");
originalData.RenameColumn(columnIndex, name);
}
public void RenameColumns(IList names) {
if (IsFiltered)
throw new InvalidOperationException("RenameColumns not possible while data is filtered");
originalData.RenameColumns(names);
}
public bool AreAllStringColumns(IEnumerable columnIndices) {
return originalData.AreAllStringColumns(columnIndices);
}
#endregion
#region Variables
public IEnumerable VariableNames {
get { return ActiveData.VariableNames; }
}
public IEnumerable GetDoubleVariableNames() {
return originalData.GetDoubleVariableNames();
}
public string GetVariableName(int columnIndex) {
return ActiveData.GetVariableName(columnIndex);
}
public int GetColumnIndex(string variableName) {
return ActiveData.GetColumnIndex(variableName);
}
public bool VariableHasType(int columnIndex) {
return originalData.VariableHasType(columnIndex);
}
public Type GetVariableType(int columnIndex) {
return ActiveData.GetVariableType(columnIndex);
}
public IList InputVariables {
get { return ActiveData.InputVariables; }
}
public string TargetVariable {
get { return ActiveData.TargetVariable; }
} // optional
#endregion
#region Partitions
public IntRange TrainingPartition {
get { return originalData.TrainingPartition; }
}
public IntRange TestPartition {
get { return originalData.TestPartition; }
}
#endregion
#region Transformations
public IList Transformations {
get { return originalData.Transformations; }
}
#endregion
#region Validation
public bool Validate(string value, out string errorMessage, int columnIndex) {
return originalData.Validate(value, out errorMessage, columnIndex);
}
#endregion
#region Import & Export
public void Import(IDataAnalysisProblemData problemData) {
if (IsFiltered)
throw new InvalidOperationException("Import not possible while data is filtered");
originalData.Import(problemData);
}
public Dataset ExportToDataset() {
return originalData.ExportToDataset();
}
#endregion
#region Selection
public IDictionary> Selection {
get { return originalData.Selection; }
set { originalData.Selection = value; }
}
public void ClearSelection() {
originalData.ClearSelection();
}
public event EventHandler SelectionChanged {
add { originalData.SelectionChanged += value; }
remove { originalData.SelectionChanged -= value; }
}
#endregion
#region Transactions
public event DataPreprocessingChangedEventHandler Changed {
add { originalData.Changed += value; }
remove { originalData.Changed -= value; }
}
public bool IsUndoAvailable {
get { return IsFiltered ? false : originalData.IsUndoAvailable; }
}
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();
}
#endregion
#region Filters
public void SetFilter(bool[] rowFilters) {
filteredData = (IPreprocessingData)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.VariableHasType(i)) {
originalData.SetValues(i, filteredData.GetValues(i));
} else if (filteredData.VariableHasType(i)) {
originalData.SetValues(i, filteredData.GetValues(i));
} else if (filteredData.VariableHasType(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();
}
public bool IsFiltered {
get { return filteredData != null; }
}
public event EventHandler FilterChanged;
private void OnFilterChanged() {
if (FilterChanged != null) {
FilterChanged(this, new EventArgs());
}
}
#endregion
}
}