Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs @ 15778

Last change on this file since 15778 was 15752, checked in by fholzing, 7 years ago

#2871: Changed back to Task, abort Thread if any other View is shown

File size: 8.7 KB
RevLine 
[14348]1#region License Information
2/* HeuristicLab
[15583]3 * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[14348]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
[15665]21
[14348]22using System;
[15626]23using System.Collections.Generic;
[14348]24using System.Linq;
[15752]25using System.Threading;
26using System.Threading.Tasks;
[15637]27using HeuristicLab.Common;
[14348]28using HeuristicLab.Data;
29using HeuristicLab.MainForm;
30
31namespace HeuristicLab.Problems.DataAnalysis.Views {
32  [View("Variable Impacts")]
33  [Content(typeof(IRegressionSolution))]
34  public partial class RegressionSolutionVariableImpactsView : DataAnalysisSolutionEvaluationView {
[15727]35    #region Nested Types
[15673]36    private enum SortingCriteria {
37      ImpactValue,
38      Occurrence,
39      VariableName
40    }
[15727]41    #endregion
[15673]42
[15727]43    #region Fields
[15626]44    private Dictionary<string, double> rawVariableImpacts = new Dictionary<string, double>();
[15752]45    private Thread thread;
[15727]46    #endregion
[15626]47
[15727]48    #region Getter/Setter
[14348]49    public new IRegressionSolution Content {
50      get { return (IRegressionSolution)base.Content; }
51      set {
52        base.Content = value;
53      }
54    }
[15727]55    #endregion
[14348]56
[15727]57    #region Ctor
[14348]58    public RegressionSolutionVariableImpactsView()
59      : base() {
60      InitializeComponent();
[15665]61
62      //Little workaround. If you fill the ComboBox-Items in the other partial class, the UI-Designer will moan.
[15673]63      this.sortByComboBox.Items.AddRange(Enum.GetValues(typeof(SortingCriteria)).Cast<object>().ToArray());
64      this.sortByComboBox.SelectedItem = SortingCriteria.ImpactValue;
[15665]65
[15727]66      //Set the default values
[14348]67      this.dataPartitionComboBox.SelectedIndex = 0;
68      this.replacementComboBox.SelectedIndex = 0;
[14826]69      this.factorVarReplComboBox.SelectedIndex = 0;
[14348]70    }
[15727]71    #endregion
[14348]72
[15727]73    #region Events
[14348]74    protected override void RegisterContentEvents() {
75      base.RegisterContentEvents();
76      Content.ModelChanged += new EventHandler(Content_ModelChanged);
77      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
78    }
79
80    protected override void DeregisterContentEvents() {
81      base.DeregisterContentEvents();
82      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
83      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
84    }
85
86    protected virtual void Content_ProblemDataChanged(object sender, EventArgs e) {
87      OnContentChanged();
88    }
89
90    protected virtual void Content_ModelChanged(object sender, EventArgs e) {
91      OnContentChanged();
92    }
93
94    protected override void OnContentChanged() {
95      base.OnContentChanged();
96      if (Content == null) {
97        variableImactsArrayView.Content = null;
98      } else {
[15752]99        UpdateVariableImpact();
[14348]100      }
101    }
102
[15752]103    private void RegressionSolutionVariableImpactsView_VisibleChanged(object sender, EventArgs e) {
104      if (thread == null) { return; }
[15665]105
[15752]106      if (thread.IsAlive) { thread.Abort(); }
107      thread = null;
108    }
109
110
[15665]111    private void dataPartitionComboBox_SelectedIndexChanged(object sender, EventArgs e) {
[15752]112      UpdateVariableImpact();
[15665]113    }
114
115    private void replacementComboBox_SelectedIndexChanged(object sender, EventArgs e) {
[15752]116      UpdateVariableImpact();
[15665]117    }
118
119    private void sortByComboBox_SelectedIndexChanged(object sender, EventArgs e) {
120      //Update the default ordering (asc,desc), but remove the eventHandler beforehand (otherwise the data would be ordered twice)
121      ascendingCheckBox.CheckedChanged -= ascendingCheckBox_CheckedChanged;
[15673]122      switch ((SortingCriteria)sortByComboBox.SelectedItem) {
123        case SortingCriteria.ImpactValue:
[15665]124          ascendingCheckBox.Checked = false;
125          break;
[15673]126        case SortingCriteria.Occurrence:
[15665]127          ascendingCheckBox.Checked = true;
128          break;
[15673]129        case SortingCriteria.VariableName:
[15665]130          ascendingCheckBox.Checked = true;
131          break;
132        default:
[15673]133          throw new NotImplementedException("Ordering for selected SortingCriteria not implemented");
[15665]134      }
135      ascendingCheckBox.CheckedChanged += ascendingCheckBox_CheckedChanged;
136
137      UpdateDataOrdering();
138    }
139
140    private void ascendingCheckBox_CheckedChanged(object sender, EventArgs e) {
141      UpdateDataOrdering();
142    }
[15727]143
[15665]144    #endregion
145
[15727]146    #region Helper Methods   
[15752]147    private void UpdateVariableImpact() {
[15727]148      //Check if the selection is valid
[15673]149      if (Content == null) { return; }
150      if (replacementComboBox.SelectedIndex < 0) { return; }
151      if (dataPartitionComboBox.SelectedIndex < 0) { return; }
152      if (factorVarReplComboBox.SelectedIndex < 0) { return; }
153
[15727]154      //Prepare arguments
[15673]155      var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
156      var replMethod = (RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum)replacementComboBox.Items[replacementComboBox.SelectedIndex];
157      var factorReplMethod = (RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum)factorVarReplComboBox.Items[factorVarReplComboBox.SelectedIndex];
158      var dataPartition = (RegressionSolutionVariableImpactsCalculator.DataPartitionEnum)dataPartitionComboBox.SelectedItem;
159
[15752]160      variableImactsArrayView.Caption = Content.Name + " Variable Impacts";
161
162      mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name);
163
164      Task.Factory.StartNew(() => {
165        thread = Thread.CurrentThread;
166        //Remember the original ordering of the variables
167        var impacts = RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content, dataPartition, replMethod, factorReplMethod);
168        var problemData = Content.ProblemData;
169        var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(Content.Model.VariablesUsedForPrediction));
170        var originalVariableOrdering = problemData.Dataset.VariableNames.Where(v => inputvariables.Contains(v)).Where(problemData.Dataset.VariableHasType<double>).ToList();
171
172        rawVariableImpacts.Clear();
173        originalVariableOrdering.ForEach(v => rawVariableImpacts.Add(v, impacts.First(vv => vv.Item1 == v).Item2));
174      }).ContinueWith((o) => {
175        UpdateDataOrdering();
176        mainForm.RemoveOperationProgressFromView(this);
177        thread = null;
178      }, TaskScheduler.FromCurrentSynchronizationContext());
[14348]179    }
180
[15626]181    /// <summary>
182    /// Updates the <see cref="variableImactsArrayView"/> according to the selected ordering <see cref="ascendingCheckBox"/> of the selected Column <see cref="sortByComboBox"/>
183    /// The default is "Descending" by "VariableImpact" (as in previous versions)
184    /// </summary>
185    private void UpdateDataOrdering() {
[15665]186      //Check if valid sortingCriteria is selected and data exists
[15673]187      if (sortByComboBox.SelectedIndex == -1) { return; }
188      if (rawVariableImpacts == null) { return; }
189      if (!rawVariableImpacts.Any()) { return; }
[15665]190
[15673]191      var selectedItem = (SortingCriteria)sortByComboBox.SelectedItem;
[15626]192      bool ascending = ascendingCheckBox.Checked;
193
[15665]194      IEnumerable<KeyValuePair<string, double>> orderedEntries = null;
[15626]195
[15665]196      //Sort accordingly
197      switch (selectedItem) {
[15673]198        case SortingCriteria.ImpactValue:
199          orderedEntries = rawVariableImpacts.OrderBy(v => v.Value);
[15665]200          break;
[15673]201        case SortingCriteria.Occurrence:
202          orderedEntries = rawVariableImpacts;
[15665]203          break;
[15673]204        case SortingCriteria.VariableName:
205          orderedEntries = rawVariableImpacts.OrderBy(v => v.Key, new NaturalStringComparer());
[15665]206          break;
207        default:
[15673]208          throw new NotImplementedException("Ordering for selected SortingCriteria not implemented");
[15626]209      }
210
[15673]211      if (!ascending) { orderedEntries = orderedEntries.Reverse(); }
212
[15665]213      //Write the data back
214      var impactArray = new DoubleArray(orderedEntries.Select(i => i.Value).ToArray()) {
215        ElementNames = orderedEntries.Select(i => i.Key)
216      };
[15727]217
[15752]218      //Could be, if the View was closed
[15727]219      if (!variableImactsArrayView.IsDisposed) {
220        variableImactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly();
221      }
[15626]222    }
223    #endregion
[14348]224  }
225}
Note: See TracBrowser for help on using the repository browser.