source: branches/2906_Transformations/HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingTransformation.cs @ 15865

Last change on this file since 15865 was 15865, checked in by pfleck, 3 years ago

#2906 Added PreprocessingTransformation as a custom view-model for transformations in preprocessing.

File size: 6.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Linq;
26using System.Runtime.CompilerServices;
27using HeuristicLab.Common;
28using HeuristicLab.Core;
29using HeuristicLab.Data;
30using HeuristicLab.Parameters;
31using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
32using HeuristicLab.PluginInfrastructure;
33using HeuristicLab.Problems.DataAnalysis;
34
35namespace HeuristicLab.DataPreprocessing {
36  [Item("Preprocessing Transformation", "")]
37  [StorableClass]
38  public class PreprocessingTransformation : ParameterizedNamedItem, INotifyPropertyChanged {
39    #region Parameters
40    public IConstrainedValueParameter<StringValue> OriginalVariableParameter {
41      get { return (IConstrainedValueParameter<StringValue>)Parameters["Original Variable"]; }
42    }
43
44    public IConstrainedValueParameter<StringValue> TransformedVariableParameter {
45      get { return (IConstrainedValueParameter<StringValue>)Parameters["Transformed Variable"]; }
46    }
47
48    public IConstrainedValueParameter<ITransformation> TransformationParameter {
49      get { return (IConstrainedValueParameter<ITransformation>)Parameters["Transformation"]; }
50    }
51    #endregion
52
53    #region Properties
54    public string OriginalVariable {
55      get { return OriginalVariableParameter.Value.Value; }
56      set { SetConstrainedValue(OriginalVariableParameter, value); }
57    }
58
59    public string TransformedVariable {
60      get { return TransformedVariableParameter.Value.Value; }
61      set { SetConstrainedValue(TransformedVariableParameter, value); }
62    }
63
64    public ITransformation Transformation {
65      get { return TransformationParameter.Value; }
66      set { TransformationParameter.Value = value; }
67    }
68
69    public bool IsApplied {
70      get { return isApplied; }
71      set { if (IsApplied != value) { isApplied = value; OnPropertyChanged(); } }
72    }
73    private bool isApplied;
74
75    private static void SetConstrainedValue(IConstrainedValueParameter<StringValue> parameter, string value, [CallerMemberName] string caller = null) {
76      if (value == null) throw new ArgumentNullException(caller);
77      if (value == parameter.Value.Value) return;
78
79      var matchingValue = parameter.ValidValues.SingleOrDefault(v => v.Value == value);
80      if (matchingValue == null) throw new ArgumentException("The provided value is not valid.", caller);
81      parameter.Value = matchingValue;
82    }
83    #endregion
84
85    #region Constructor, Cloning & Persistence
86    public PreprocessingTransformation(IEnumerable<StringValue> variableNames)
87      : base() {
88      var originalVariables = new ItemSet<StringValue>(variableNames.Select(x => x.AsReadOnly()));
89      var transformedVariables = new ItemSet<StringValue>(variableNames.Select(x => x.AsReadOnly()));
90      Parameters.Add(new ConstrainedValueParameter<StringValue>("Original Variable", new ItemSet<StringValue>(originalVariables), originalVariables.FirstOrDefault()));
91      Parameters.Add(new ConstrainedValueParameter<StringValue>("Transformed Variable", new ItemSet<StringValue>(transformedVariables), transformedVariables.FirstOrDefault()));
92      var transformations = new ItemSet<ITransformation>(ApplicationManager.Manager.GetInstances<ITransformation>());
93      Parameters.Add(new ConstrainedValueParameter<ITransformation>("Transformation", transformations, transformations.OfType<IdentityTransformation>().Single()));
94
95      IsApplied = false;
96
97      RegisterEventHandlers();
98    }
99
100    protected PreprocessingTransformation(PreprocessingTransformation original, Cloner cloner)
101      : base(original, cloner) {
102      RegisterEventHandlers();
103    }
104
105    public override IDeepCloneable Clone(Cloner cloner) {
106      return new PreprocessingTransformation(this, cloner);
107    }
108
109    [StorableConstructor]
110    protected PreprocessingTransformation(bool deserializing)
111      : base(deserializing) { }
112
113    [StorableHook(HookType.AfterDeserialization)]
114    private void AfterDeserialization() {
115      RegisterEventHandlers();
116    }
117    #endregion
118
119    #region Event-Handling
120    private void RegisterEventHandlers() {
121      OriginalVariableParameter.ValueChanged += OriginalVariableParameter_ValueChanged;
122      TransformedVariableParameter.ValueChanged += TransformedVariableParameter_ValueChanged;
123      TransformationParameter.ValueChanged += TransformationParameter_ValueChanged;
124    }
125
126    private void OriginalVariableParameter_ValueChanged(object sender, EventArgs e) {
127      OriginalVariableParameter.Value.ValueChanged += OriginalVariableParameterValue_ValueChanged;
128      OnPropertyChanged(nameof(OriginalVariable));
129    }
130    private void OriginalVariableParameterValue_ValueChanged(object sender, EventArgs e) {
131      OnPropertyChanged(nameof(OriginalVariable));
132    }
133
134    private void TransformedVariableParameter_ValueChanged(object sender, EventArgs e) {
135      TransformedVariableParameter.Value.ValueChanged += TransformedVariableParameterValue_ValueChanged;
136      OnPropertyChanged(nameof(TransformedVariable));
137    }
138    private void TransformedVariableParameterValue_ValueChanged(object sender, EventArgs e) {
139      OnPropertyChanged(nameof(TransformedVariable));
140    }
141
142    private void TransformationParameter_ValueChanged(object sender, EventArgs e) {
143      OnPropertyChanged(nameof(Transformation));
144    }
145    #endregion
146
147    public override string ToString() {
148      return $"{Transformation} ({OriginalVariable} -> {TransformedVariable})";
149    }
150
151    public event PropertyChangedEventHandler PropertyChanged;
152    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
153      OnToStringChanged();
154      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
155    }
156  }
157}
Note: See TracBrowser for help on using the repository browser.